文档讲解:代码随想录
视频讲解:代码随想录B站账号
状态:看了视频题解和文章解析后做出来了
class Solution:
def maxProfit(self, prices: List[int]) -> int:
n = len(prices)
if n < 2:
return 0
dp = [[0]*3 for _ in range(len(prices))]
dp[0][0] = -prices[0]
for i in range(1, len(prices)):
dp[i][0] = max(dp[i-1][0], dp[i-1][2] - prices[i])
dp[i][1] = dp[i-1][0] + prices[i]
dp[i][2] = max(dp[i-1][2], dp[i-1][1])
return max(dp[-1][1], dp[-1][2])
1. 确定dp数组以及下标的含义
这道题引入了冷冻期的概念,也就是卖出以后有一天不能交易。
这里需要定义三个状态:
(1)状态0:持有股票
(2)状态1:不持有股票且进入冷冻期
(3)状态2:不持有股票且不在冷冻期
2. 确定递推公式
- 状态0的持有股票有两种情况,第一种是延续昨天持有的状态,第二种是今天买了股票:
dp[i][0] = max(dp[i-1][0], dp[i-1][2] - prices[i]),注意买股票沿用的昨天不在冷冻期的状态,如果昨天进入了冷冻期那今天就不能买股票了。
- 状态1只有一种情况,也就是昨天持有股票今天卖了并进入冷冻期
dp[i][1] = dp[i-1][0] + prices[i]
- 状态2有两种情况,延续之前的不持有股票状态和刚从冷冻期解冻且不买股票。
dp[i][2] = max(dp[i-1][1], dp[i-1][2])
3. dp数组的初始化
只有状态0需要初始化为-prices[i],因为状态0是第一天就持有股票。
4. 遍历顺序
递推公式中有i-1,所以从前往后遍历
5. dp数组举例
class Solution:
def maxProfit(self, prices: List[int], fee: int) -> int:
if len(prices) == 0:
return 0
dp = [[0]*2 for _ in range(len(prices))]
dp[0][0] = -prices[0]
for i in range(1, len(prices)):
dp[i][0] = max(dp[i-1][0], dp[i-1][1] - prices[i])
dp[i][1] = max(dp[i-1][1], dp[i-1][0] + prices[i] - fee)
return dp[-1][1]
和最常规的买卖股票题的唯一区别就是加了一个手续费,只有在卖出的时候减去手续费fee即可。
唯一差别在于递推公式部分,所以本篇也就不按照动规五部曲详细讲解了,主要讲解一下递推公式部分。
这里重申一下dp数组的含义:
dp[i][0] 表示第i天持有股票所省最多现金。 dp[i][1] 表示第i天不持有股票所得最多现金
如果第i天持有股票即dp[i][0], 那么可以由两个状态推出来
所以:dp[i][0] = max(dp[i - 1][0], dp[i - 1][1] - prices[i]);
在来看看如果第i天不持有股票即dp[i][1]的情况, 依然可以由两个状态推出来
所以:dp[i][1] = max(dp[i - 1][1], dp[i - 1][0] + prices[i] - fee);
最后返回的是最后一天不持有股票时候的现金数。