Best Time to Buy and Sell Stock 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 twotransactions.

Have you met this question in a real interview?  
Yes
Example

Given an example [4,4,6,1,1,4,2,5], return 6.

Note

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

这里和之前的几个不同之处在于,现在是最多只能交易两次。那也就是说,按理应该将其划分为两段,[0, i], [i + 1, len -1], 分别求两段能够获得的最大利润,然后加起来就是两次交易可以获取的最大利润。定义两个数组A[i]表示前i个可以获取的最大利润,B[i]表示后i个可以获取的最大利润。对于数组A[i]就用Best Time to Buy and Sell Stock的方法求解,那么对于数组B[i], 如何高效的求解?在求解A[i]的时候,是把第i个当做卖出的时间点, 那么在求解B[i]的时候应该将i点看做在第i点购买的时候,产生的最大利润,明白了这一点,那么B[i] = [i + 1, len -1]中的最大值 - prices[i],这样求出A[i],B[i]之后就只要再遍历一遍,求出最大的利润。

class Solution {
public:
    /**
     * @param prices: Given an integer array
     * @return: Maximum profit
     */
    //维护两个数组,数组A[i]表示以前i个可以获得的最大利润,B[i]表示以后i个可以获得的最大利润
    int maxProfit(vector<int> &prices) {
        // write your code here
        int len = prices.size();
        if(len < 2)
            return 0;
        int *A = new int[len], *B = new int[len + 1];
        A[0] = 0;
        B[len - 1] = 0;
        B[len] = 0;
        int curMin = prices[0], tmpMax = 0;
        for(int i = 1; i < len; ++i)
        {
            A[i] = (prices[i] - curMin) >= tmpMax ? prices[i] - curMin : tmpMax;
            tmpMax = tmpMax < A[i] ? A[i] : tmpMax;
            curMin = curMin > prices[i] ? prices[i] : curMin;
        }
        
        int curMax = prices[len - 1];
        tmpMax = 0;
        for(int i = len - 2; i >= 0; --i)
        {
            B[i] = (curMax - prices[i]) >= tmpMax ? curMax - prices[i] : tmpMax;
            tmpMax = tmpMax < B[i] ? B[i] : tmpMax;
            curMax = curMax < prices[i] ? prices[i] : curMax;
        }
        
        int Max = 0;
        for(int i = 0; i < len; ++i)
        {
            Max = Max < A[i] + B[i + 1] ? A[i] + B[i + 1] : Max;
        }
        
        return Max;
    }
};


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值