题目
给定一个整数数组 prices ,它的第 i 个元素 prices[i] 是一支给定的股票在第 i 天的价格。
设计一个算法来计算你所能获取的最大利润。你最多可以完成 k 笔交易。
注意:你不能同时参与多笔交易(你必须在再次购买前出售掉之前的股票)。
题解
最优化问题考虑用动态规划。
看最终结果受哪些因素影响,穷举不同因素的所有状态值,就可以推导出最终结果。
最终收益受哪些维度的状态变化影响?
- 在第几天买入或卖出肯定是会影响最终收益,可能某一天突然暴涨。
- 交易次数越多,可能赚取的收益越大。
- 在第
i
天可以选择的操作有三种:买入、卖出、什么也不做。
什么也不做包含了两种状态:买入过后什么也不做、卖出过后什么也不做。归纳合并一下,这些操作会产生的结果状态是:第i
天持有或不持有股票。股票持有状态也会影响最终收益。
所以从结果上看,一共有三种纬度的状态变化:
- 第几天做出选择
- 已经交易了多少次
- 当前是否持有股票
买入的时候算一次交易,还是卖出的时候算一次交易?
其实都可以,不影响最终结果,只是状态转移过程会有所变化。
这里定义买入的时候算一次交易。
状态转移方程
dp[i][j][k]
表示,前i
天,交易了j
次,在第i
天持有或不持有股票,所获得最大的收益。其中k == 0
表示不持有,k == 1
表示持有。
dp[i][j][0]
怎么得来?- 第
i - 1
天没有持有股票,第i
天什么也不操作。dp[i][j][0] = dp[i - 1][j][0]
- 第
i - 1
天持有股票,第i
天卖出。dp[i][j][0] = dp[i - 1][j][] + prices[i]
- 第
dp[i][j][1]
怎么得来?- 第
i - 1
天持有股票,第i
天什么也不操作。dp[i][j][1] = dp[i - 1][j][1]
- 第
i - 1
天没有持有股票,第i
天买入。dp[i][j][1] = dp[i - 1][j - 1][0] - prices[i]
- 第
边界处理
- 第0天
- 持有股票的话,不多少次交易,只能直接买入一次。
- 不持有股票的话,收益就是0。
- 第
i
天之前都没有交易即j == 0
),第i
天要交易操作就买入。
空间优化
如果给定的最多交易次数k
非常大,状态数组开辟空间也会非常大,的。
交易上限是多少?
一次交易要买入和卖出,总共n天,交易次数不应该超过n / 2。
交易次数超过n / 2要怎么办?
这就等于不限交易次数,与LeetCode.122.买卖股票的最佳时机 II(简单)解法相同,可以复用这种情况下最优化空间的解答。
1 | class Solution { |
复杂度
- 时间复杂度
O(n * k)
。 k >= n / 2
时,空间复杂度O(1)
;k < n / 2
时,空间复杂度O(n * k)
。