1. 程式人生 > >LeetCode:309. Best Time to Buy and Sell Stock with Cooldown

LeetCode:309. Best Time to Buy and Sell Stock with Cooldown

買賣股票系列的第5題。題目是:

Say you have an array for which the ith element is the price of a
given stock on day i.

Design an algorithm to find the maximum profit. You may complete as
many transactions as you like (ie, buy one and sell one share of the
stock multiple times) with the following restrictions:

You may not engage in multiple transactions at the same time (ie, you
must sell the stock before you buy again). After you sell your stock,
you cannot buy stock on next day. (ie, cooldown 1 day)

這裡的特殊要求是賣出一次,需要等一天,才能重新買入。
題目不難,只是優化方面需要注意一下。

這題應該用動態規劃來做。
狀態定義:dp[i]:第i天能獲得的最大利潤
狀態轉移方程:dp[i] = max(dp[i-1], dp[j-2] + (prices[i] - prices[j])), 0 <= j < i,這裡分別對應在第i天不賣和賣的情況。
很快寫出程式碼:

class Solution {
public:
    int maxProfit(vector<int>& prices) {
        if (prices.empty() || prices.size() == 1)
            return 0;
        int sz = prices.size();
        vector<int> dp(sz, 0);
        dp[1] = prices[1] > prices[0] ? prices[1] - prices[0] : 0;
        for (int i = 2; i < sz; ++i) {
            dp[i] = dp[i-1];
            for (int j = 0; j < i; ++j) {
                int temp = j-2 < 0 ? prices[i] - prices[j] : dp[j-2] + prices[i] - prices[j];
                if (temp > dp[i])
                    dp[i] = temp;
            }
        }
        return dp.back();
    }
};

程式碼寫成這樣會有效率低的問題。
我們觀察狀態轉移方程,將後半部分化為:(dp[j-2] - prices[j]) + prices[i],
對於不同的i,(dp[j-2] - prices[j])的前面部分部分是一樣的,也就是上面的程式碼重複計算了這一部分。進行優化後的程式碼是:

class Solution {
public:
    int maxProfit(vector<int>& prices) {
        if (prices.empty() || prices.size() == 1)
            return 0;
        int sz = prices.size();
        vector<int> dp(sz, 0);
        dp[1] = prices[1] > prices[0] ? prices[1] - prices[0] : 0;
        int tempMax = max(-prices[0], -prices[1]);//tempMax = dp[j-2] - prices[j]
        for (int i = 2; i < sz; ++i) {
            tempMax = max(tempMax, dp[i-2] - prices[i]);
            dp[i] = max(dp[i-1], tempMax + prices[i]);
        }
        return dp.back();
    }
};

時間複雜度由原來的O(n^2)降低到O(n),優化的結果還行