Leetcode 188:买卖股票的最佳时机 IV(超详细解决方案!!!)
in leetcode with 0 comment

Leetcode 188:买卖股票的最佳时机 IV(超详细解决方案!!!)

in leetcode with 0 comment

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

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

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

示例 1:

输入: [2,4,1], k = 2
输出: 2
解释: 在第 1 天 (股票价格 = 2) 的时候买入,在第 2 天 (股票价格 = 4) 的时候卖出,这笔交易所能获得利润 = 4-2 = 2 。

示例 2:

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

解题思路

这是之前问题的扩展。

Leetcode 121:买卖股票的最佳时机(最详细的解法!!!)

Leetcode 122:买卖股票的最佳时机II(最详细的解法!!!)

Leetcode 123:买卖股票的最佳时机III(最详细的解法!!!)

因为这个问题中有最多k笔交易的限制,所以我们不难想到通过123号问题的解法来解,但是这里有一个问题,就是当2k>len(prices)的时候我们需要开辟很大的存储空间,在leetcode上提交的话会出现内存溢出的错误。怎么办?当2k>len(prices)的时候,其实可以将问题转化为122号问题,也就是交易次数不限。为什么是2k?因为买和卖是两个操作。

好,现在我们的思路就很明确,当2k>len(prices)的时候,我们通过贪心来解决;当2k<=len(prices)的时候,我们通过动态规划来解决。我们也可以将2k=len(prices)通过贪心解决,其实是一样的,这是一个临界问题。

class Solution:
    def maxProfit(self, k, prices):
        """
        :type k: int
        :type prices: List[int]
        :rtype: int
        """
        p_len = len(prices)
        if k >= p_len//2:
            return self.greedy(prices)
        
        buy, sell = [-prices[0]]*k , [0]*(k+1)
        for p in prices[1:]:
            for i in range(k):
                buy[i] = max(buy[i], sell[i-1]-p)
                sell[i] = max(sell[i], buy[i]+p)
                
        return max(sell)
        
    def greedy(self, prices):
        res = 0
        for i in range(1, len(prices)):
            if prices[i] > prices[i-1]:
                res += prices[i] - prices[i-1]
                
        return res

这里需要注意的就是buy的初始化,对sell的初始化我们使用了k+1,为什么?为了避免k=0的时候此时sell为空,我们无法调用max函数。其余的地方都是顺理成章的。

我将该问题的其他语言版本添加到了我的GitHub Leetcode

如有问题,希望大家指出!!!

「如果我的文章对你有很大帮助,那么不妨~!」

coordinate

谢谢老板O(∩_∩)O~

使用微信扫描二维码完成支付

Responses