393. 买卖股票的最佳时机 IV
中文English
给定数组 prices
, 其中第 i
个元素代表某只股票在第 i
天第价格.
你最多可以完成 k
笔交易. 问最大的利润是多少?
样例
样例 1:
输入: k = 2, prices = [4, 4, 6, 1, 1, 4, 2 ,5]
输出: 6
解释: 以 4 买入, 以 6 卖出. 然后再以 1 买入, 以 5 卖出. 利润为 2 + 4 = 6.
样例 2:
输入: k = 1, prices = [3, 2, 1]
输出: 0
解释: 不进行交易
挑战
O(nk) 时间复杂度. n
是 prices
数组的大小.
注意事项
你不可以同时参与多笔交易(你必须在再次购买前出售掉之前的股票)
输入测试数据 (每行一个参数)如何理解测试数据?
class Solution: ''' 大致思路: 1.如果是K >= len(prices) // 2的话,则说明是可以进行任意次数的交易,直接取每次买卖股票的获得的收益相加即可,全部收益值,和买卖股票II类似 2.如果 K < len(prices) // 2的话,则说明有k*2 + 1种状态 和买卖股票III类似 ''' def maxProfit(self, K, prices): if not prices or len(prices) == 0:return 0 #第一种情况,如果K >= len(prices) // 2 max_num = 0 l = len(prices) if (K >= l // 2): for i in range(1, l): if prices[i] > prices[i - 1]: max_num += prices[i] - prices[i - 1] return max_num #第二种情况 #初始化 #状态 s = 2*K + 1 f = [[-sys.maxsize]*(s + 1) for _ in range(l + 1)] #如果是前0天的话,只有一种可能,处于无股票状态,获利0 f[0][1] = 0 #计算顺序 for i in range(1,l + 1): #处于无股票状态,奇数位 for j in range(1,s + 1, 2): f[i][j] = f[i - 1][j] if (i - 2 >= 0) and (f[i - 1][j - 1] != -sys.maxsize): f[i][j] = max(f[i][j],f[i - 1][j - 1] + prices[i - 1] - prices[i - 2]) #处于有股票状态,偶数位 for j in range(2,s + 1, 2): #上一天刚好无股票,今天刚好买入,不获利 f[i][j] = f[i - 1][j - 1] + 0 if (i - 2 >= 0) and (f[i - 1][j] != -sys.maxsize): f[i][j] = max(f[i][j],f[i - 1][j] + prices[i - 1] - prices[i - 2]) #取出最大值即可 for m in range(1, s + 1,2): if f[i][m] > max_num: max_num = f[i][m] return max_num #result = Solution().maxProfit(10, [3, 2, 1,4,6,8,9,87,65]) #print(result)
优化版本:滚动数组,空间复杂度O(2*(K + 1) * 3) 时间复杂度O(K*len(prices))
##滚动数组 优化版本 class Solution: ''' 大致思路: 1.如果是K >= len(prices) // 2的话,则说明是可以进行任意次数的交易,直接取每次买卖股票的获得的收益相加即可,全部收益值 2.如果 K < len(prices) // 2的话,则说明有k*2 + 1种状态 和买卖股票III类似 ''' def maxProfit(self, K, prices): if not prices or len(prices) == 0:return 0 #第一种情况,如果K >= len(prices) // 2 max_num = 0 l = len(prices) if (K >= l // 2): for i in range(1, l): if prices[i] > prices[i - 1]: max_num += prices[i] - prices[i - 1] return max_num #第二种情况 #初始化 #状态 s = 2*K + 1 f = [[-sys.maxsize]*(s + 1) for _ in range(3)] #如果是前0天的话,只有一种可能,处于无股票状态,获利0 f[0][1] = 0 #计算顺序 for i in range(1,l + 1): index = i%3 #处于无股票状态,奇数位 for j in range(1,s + 1, 2): f[index][j] = f[index - 1][j] if (i - 2 >= 0) and (f[index - 1][j - 1] != -sys.maxsize): f[index][j] = max(f[index][j],f[index - 1][j - 1] + prices[i - 1] - prices[i - 2]) #处于有股票状态,偶数位 for j in range(2,s + 1, 2): #上一天刚好无股票,今天刚好买入,不获利 f[index][j] = f[index - 1][j - 1] + 0 if (i - 2 >= 0) and (f[index - 1][j] != -sys.maxsize): f[index][j] = max(f[index][j],f[index - 1][j] + prices[i - 1] - prices[i - 2]) #取出最大值即可 for m in range(1, s + 1,2): if f[index][m] > max_num: max_num = f[index][m] #print(f) return max_num result = Solution().maxProfit(2, [4, 4, 6, 1, 1, 4, 2 ,5]) print(result)