【ATT】Best Time to Buy and Sell Stock III

Q: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).

A: 允许最多交易两次。

本质上是动态规划题目。

 考虑Best Time to Buy and Sell Stock这道题,用O(n)的时间遍历数组就能找到maxProfit。本题也利用这个思想。

将数组分成两部分,分别求两部分的maxProfit,划分点可能在数组的任何位置。假设划分点是i。

forwardProfit[i]表示prices[0]~prices[i]之间交易一次的maxProfit;计算forwardProfit要从数组从头到尾扫描,记录valley。

forwardProfit[i] = max(forwardProfit[i-1],prices[i]-valley);

backProfit[i]表示prices[i]~prices[n-1]之间交易一次的maxProfit;计算backProfit要从数组末尾往前扫描,记录peek

 backProfit[i] = max(backProfit[i+1],peek-prices[i]);   //注意是backProfit[i+1]

那么总的maxProfit = max(forwardProfit[i]+backProfit[i]) i取0~n-1

注意:为什么不是forwardProfit[i-1]+backProfit[i]取最大值呢?!!!!!!!!要注意。
因为题目要求最多交易两次,因此能够交易一次,当前半部分sell的时间与后半部分buy的时间相等时,其实等价于只交易一次。
    int maxProfit(vector<int> &prices) {
        // Start typing your C/C++ solution below
        // DO NOT write int main() function
        if(prices.empty())
            return 0;
        vector<int> forwardProfit(prices.size());
        vector<int> backProfit(prices.size());
        
        int valley = prices[0];
        forwardProfit[0] = 0;
        int i;
        int maxProfit = 0;
        for(i=1;i<prices.size();i++)
        {
            valley = min(valley,prices[i]);
            forwardProfit[i] = max(forwardProfit[i-1],prices[i]-valley);
        }
        
        int peek = prices[prices.size()-1];
        backProfit[prices.size()-1] = 0;
        for(i=prices.size()-2;i>=0;i--)
        {
            peek = max(prices[i],peek);
            backProfit[i] = max(backProfit[i+1],peek-prices[i]);
            
            maxProfit = max(maxProfit,forwardProfit[i]+backProfit[i]);
        }
        
        return maxProfit;
    }

  

posted @ 2013-09-20 16:45  summer_zhou  阅读(176)  评论(0编辑  收藏  举报