[LeetCode]107. Best Time to Buy and Sell Stock III股票买卖III

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 at most two transactions.

Note:
You may not engage in multiple transactions at the same time (ie, you must sell the stock before you buy again).

 

解法:与股票买卖I、股票买卖II又有些不同,这次要求最多交易两次,还是动态规划的方法。我们可以分别计算出在第i(1<=i<=n)天前交易一次股票所能获得的最大收益和第i(1<=i<=n)天后交易一次股票所能获得的最大收益,于是能计算出以第i(1<=i<=n)天为分割交易两次所能获得的最大收益,于是一共交易两次所能获得的最大收益必是所有收益的最大值。注意计算前后收益时都必须包含第i天,因为当天可以先卖出然后买进。

class Solution {
public:
    int maxProfit(vector<int> &prices) {
        int n = prices.size(), maxp = 0;
        if (n < 2) return 0;
        vector< vector<int> > maxOne(2, vector<int>(n, 0));
        maxOne[0][0] = 0;
        maxOne[1][n - 1] = 0;
        for (int i = 1; i < n; ++i)
            maxOne[0][i] = maxProfitOfOne(prices, 0, i);
        for (int i = n - 2; i >= 0; --i)
            maxOne[1][i] = maxProfitOfOne(prices, i, n - 1);
        for (int i = 0; i < n; ++i)
            maxp = max(maxp, maxOne[0][i] + maxOne[1][i]);
        return maxp;
    }
private:
    int maxProfitOfOne(vector<int>& prices, int beg, int end) {
        int maxp = 0, curMin = prices[beg];
        for (int i = beg + 1; i <= end; ++i) {
            curMin = min(curMin, prices[i]);
            maxp = max(maxp, prices[i] - curMin);
        }
        return maxp;
    }
};

直接调用maxProfitOfOne会超时Time Limit Exceeded,因为计算第i天前后各交易一次的最大收益时要遍历[0,i]和[i,n-1]两半数组,这样相当于整个时间复杂度为O(n^2)了,必须加以改进。

注意到第i天前的最大收益要么是第i-1天前的最大收益,要么是第i天的股票价格减去前i-1天的最低价格;而第i天后的最大收益要么是第i+1天后的最大收益,要么是后i+1天的最高股票价格减去第i天的价格,因此可以简化如下:

class Solution {
public:
    int maxProfit(int k, vector<int>& prices) {
        int n = prices.size(), maxp = 0;
        if (n < 2) return 0;
        int curMin = prices[0];
        vector< vector<int> > maxOne(2, vector<int>(n, 0));
        maxOne[0][0] = 0;
        maxOne[1][n - 1] = 0;
        for (int i = 1; i < n; ++i) {
        maxOne[0][i] = max(maxOne[0][i - 1], prices[i] - curMin);
            curMin = min(curMin, prices[i]);
        }
        int curMax = prices[n - 1];
        for (int i = n - 2; i >= 0; --i) {
            maxOne[1][i] = max(maxOne[1][i + 1], curMax - prices[i]);
            curMax = max(curMax, prices[i]);

        }
        for (int i = 0; i < n; ++i)
            maxp = max(maxp, maxOne[0][i] + maxOne[1][i]);
        return maxp;
    }
};

 其他解法参见http://www.cnblogs.com/grandyang/p/4281975.html

posted @ 2015-12-11 20:14  AprilCheny  阅读(187)  评论(0编辑  收藏  举报