【leetcode】123 买卖股票的最佳时机 III(动态规划)

题目链接:https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock-iii/

题目描述

给定一个数组,它的第 i 个元素是一支给定的股票在第 i 天的价格。

设计一个算法来计算你所能获取的最大利润。你最多可以完成 两笔 交易。

注意: 你不能同时参与多笔交易(你必须在再次购买前出售掉之前的股票)。

示例 1:

输入: [3,3,5,0,0,3,1,4]
输出: 6
解释: 在第 4 天(股票价格 = 0)的时候买入,在第 6 天(股票价格 = 3)的时候卖出,这笔交易所能获得利润 = 3-0 = 3 。
     随后,在第 7 天(股票价格 = 1)的时候买入,在第 8 天 (股票价格 = 4)的时候卖出,这笔交易所能获得利润 = 4-1 = 3 。

示例 2:

输入: [1,2,3,4,5]
输出: 4
解释: 在第 1 天(股票价格 = 1)的时候买入,在第 5 天 (股票价格 = 5)的时候卖出, 这笔交易所能获得利润 = 5-1 = 4 。   
     注意你不能在第 1 天和第 2 天接连购买股票,之后再将它们卖出。   
     因为这样属于同时参与了多笔交易,你必须在再次购买前出售掉之前的股票。

思路

一个错误的思路

经过121题和122题,本来想着通过一次遍历,取峰谷差值最大的两组之和作为最终结果,通过了190/200的用例。

class Solution {
public:
    int maxProfit(vector<int>& prices) {
        if(prices.empty()) return 0;
        int peak = prices[0];
        int valley = prices[0];
        int i = 0;
        int ret = 0;
        int diff1 = 0, diff2 = 0;
        int diffNum = 0;
        while (i< prices.size() -1){
            while(i< prices.size()-1 && prices[i]>= prices[i+1]) ++i;
            valley = prices[i];
            while(i< prices.size()-1 && prices[i]<= prices[i+1]) ++i;
            peak = prices[i];
            int diff = peak - valley;
            if(diff > 0){
                if (diff > diff2) swap(diff,diff2);
                if (diff2 > diff1) swap(diff2,diff1);
            }
        }
        return diff1 + diff2;
    }
};

错误如下 :
【leetcode】123 买卖股票的最佳时机 III(动态规划)_第1张图片
分析这个用例发现,我们错误在于用9和2的差值7去替换了(3,5)中的较小值3,最终结果为12。即当已存在两个峰谷差时,直接替换较小值不一定能得到最最优值。

        6            7
----------------  -------
|              |  |     |
1  2  4  2  5  7  2  4  9  0
|     |  |     |  |     |
-------  -------  -------
   3        5        7

动态规划方法

/*
 * 动态规划一次遍历
 * 时间复杂度 O(n) 空间复杂度O(1)
 */
class Solution {
public:
    int maxProfit(vector<int>& prices) {
        if(prices.empty()) return 0;
        vector<int> sell(2,0);
        vector<int> buy(2, INT_MIN);
        
        for(int p : prices){
            buy[0] = max(buy[0], -p);
            sell[0] = max(sell[0], buy[0] + p);
            buy[1] = max(buy[1], sell[0]-p);
            sell[1] = max(sell[1], buy[1] + p);
        }
        return sell[1];
    }
};

你可能感兴趣的:(LeetCode)