[leetcode]Best Time to Buy and Sell Stock III

先说思路。参考了这篇:http://blog.unieagle.net/2012/12/05/leetcode%E9%A2%98%E7%9B%AE%EF%BC%9Abest-time-to-buy-and-sell-stock-iii%EF%BC%8C%E4%B8%80%E7%BB%B4%E5%8A%A8%E6%80%81%E8%A7%84%E5%88%92/

我们可以看到这个相当于要分两段,取前一段和后一段的分别最大值。这样分割点遍历,最后是O(n^2)的复杂度。

然后优化后,使用一维的DP。可以降低到O(n)。也就是先从左到右扫一遍求得以i结尾的最大利润的数组,然后从右到左扫一遍求得以i开头的最大利润的数组。然后一加就可以了。

public class Solution {
    public int maxProfit(int[] prices) {
        // Start typing your Java solution below
        // DO NOT write main() function
        if (prices.length == 0 || prices.length == 1) return 0;
        int ans = 0;
        
        int max = 0;
        
        int len = prices.length;
        int historyProfit[] = new int[len];
        int futureProfit[] = new int[len];
        int valley  = prices[0];
        for (int i = 1; i < len; i++) {
        	if (prices[i] >= prices[i-1]) {
        		int val = prices[i] - valley ;
        		if (val > max) max = val;     		
        	}
        	else {
        		if (prices[i] < valley ) valley  = prices[i];
        	}
        	historyProfit[i] = max;
        }       
        
        int peek = prices[len - 1];
        ans = max;
        max = 0;
        for (int i = len - 2; i >= 1; i--) {
        	if (prices[i+1] >= prices[i]) {
        		 int val = peek - prices[i];
                 if (val > max) max = val;
        	}
        	else {
        		if (prices[i] > peek) peek = prices[i];
        	}
        	futureProfit[i] = max;
        	int p = futureProfit[i] + historyProfit[i-1];
        	if (p > ans) {
        		ans = p;
        	}
        }
        
        return ans;
    }
}

我的代码比较乱,看看参考代码多么简洁。同时,该讨论第二楼里还有关于更一般情况的讨论,有空好好看看。

class Solution {
public:
    int maxProfit(vector<int> &prices) {
        // null check
        int len = prices.size();
        if (len==0) return 0;

        vector<int> historyProfit;
        vector<int> futureProfit;
        historyProfit.assign(len,0);
        futureProfit.assign(len,0);
        int valley = prices[0];
        int peak = prices[len-1];
        int maxProfit = 0;

        // forward, calculate max profit until this time
        for (int i = 0; i<len; ++i)
        {
            valley = min(valley,prices[i]);
            if(i>0)
            {
                historyProfit[i]=max(historyProfit[i-1],prices[i]-valley);
            }
        }

        // backward, calculate max profit from now, and the sum with history
        for (int i = len-1; i>=0; --i)
        {
            peak = max(peak, prices[i]);
            if (i<len-1)
            {
                futureProfit[i]=max(futureProfit[i+1],peak-prices[i]);
            }
            maxProfit = max(maxProfit,historyProfit[i]+futureProfit[i]);
        }
        return maxProfit;
    }
};

  

posted @ 2013-08-05 19:40  阿牧遥  阅读(321)  评论(0)    收藏  举报