1. 程式人生 > >Leetcode 188:買賣股票的最佳時機 IV(超詳細解決方案!!!)

Leetcode 188:買賣股票的最佳時機 IV(超詳細解決方案!!!)

給定一個數組,它的第 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號問題的解法來解,但是這裡有一個問題,就是當k>len(prices)的時候我們就無法使用之前的方法了,這個時候其實就是122號問題,也就是交易次數不限。好,現在我們的思路就很明確,當k<=len(prices)的時候,我們通過貪心來解決,當k>len(prices)

的時候,我們通過動態規劃來解決。我們也可以將k=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的初始化,其餘的地方都是順理成章的。

我將該問題的其他語言版本新增到了我的GitHub Leetcode

如有問題,希望大家指出!!!