@@ -21,6 +21,7 @@ https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock-with-cooldown/
2121
2222## 前置知识
2323
24+ - 记忆化递归
2425- [ 动态规划] ( https://github.com/azl397985856/leetcode/blob/master/thinkings/dynamic-programming.md )
2526
2627## 公司
@@ -29,21 +30,90 @@ https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock-with-cooldown/
2930- 腾讯
3031- 字节
3132
32- ## 思路
33+ ## 记忆化递归
34+
35+ ### 思路
36+
37+ 用 f(i, state) 表示第 i 天(从 0 开始),当前状态是 state 的最大利润。
38+
39+ - state 为 0 表示手上没有股票
40+ - state 为 1 表示手上有股票
41+ - state 为 -1 表示手上没有股票,但是在冷冻期,所以不能买。
42+
43+ 那么转移方程就容易了。
44+
45+ - 如果 state 为 0,那么当前可以什么都不做,也可以买入,也就是说不能卖出了。因此最大利润就是两种的最大值。
46+
47+ ``` py
48+ max (f(i+ 1 , 0 ), f(i+ 1 , 1 ) - prices[i])
49+ ```
50+
51+ - 如果 state 为 1,那么当前可以什么都不做,也可以卖出,也就是说不能买入了。因此最大利润就是两种的最大值。
52+
53+ ``` py
54+ max (f(i+ 1 , 1 ), f(i+ 1 , - 1 ) + prices[i])
55+ ```
56+
57+ - 如果 state 为 -1,那么当前只能什么都不做,因此最大利润维持不变,但是状态变为 0。(因为冷冻期只有一天,思考下如果冷冻期是 k 天如何修改我们的逻辑?)
58+
59+ ``` py
60+ f(i+ 1 , 0 )
61+ ```
62+
63+ 临界条件就是 i == n - 1,此时如果 state == 1, 我们可以将其卖掉,否则无法卖出。
64+
65+ ### 代码
66+
67+ 代码支持:Python3
68+
69+ Python3 Code:
70+
71+ ``` py
72+ class Solution :
73+ def maxProfit (self , prices ):
74+ if not prices:
75+ return 0
76+ n = len (prices)
77+
78+ @lru_cache (None )
79+ def f (i , state ):
80+ if i == n - 1 :
81+ return prices[i] if state == 1 else 0
82+
83+ if state == - 1 :
84+ return f(i + 1 , 0 )
85+ if state == 0 :
86+ return max (f(i + 1 , 0 ), - prices[i] + f(i + 1 , 1 ))
87+ if state == 1 :
88+ return max (prices[i] + f(i + 1 , - 1 ), f(i + 1 , 1 ))
89+
90+ return f(0 , 0 )
91+
92+ ```
93+
94+ ** 复杂度分析**
95+
96+ 令 n 为数组长度。
97+
98+ - 时间复杂度: 状态总数为 3 \* n ,单个状态所需时间为 $O(1)$,因此时间复杂度为 $O(n)$
99+ - 空间复杂度:状态总数为 3 \* n ,因此空间复杂度为 $O(n)$
100+
101+ ## 动态规划
102+
103+ ### 思路
33104
34105这是一道典型的 DP 问题, DP 问题的核心是找到状态和状态转移方程。
35106
36- 这道题目的状态似乎比我们常见的那种 DP 问题要多,这里的状态有 buy sell cooldown 三种,
37- 我们可以用三个数组来表示这这三个状态,buy,sell, cooldown.
107+ 这道题目的状态似乎比我们常见的那种 DP 问题要多,这里的状态有 buy sell cooldown 三种,我们可以用三个数组来表示这这三个状态,buy,sell, cooldown。其中:
38108
39- - buy[ i] 表示第 i 天,且以 buy 结尾的最大利润
40- - sell[ i] 表示第 i 天,且以 sell 结尾的最大利润
41- - cooldown[ i] 表示第 i 天,且以 ` 什么都不做 ` (cooldown)结尾的最大利润
109+ - buy[ i] 表示第 i 天,且手里有股票(不在冷冻期)的最大利润
110+ - sell[ i] 表示第 i 天,且手里没有股票的最大利润
111+ - cooldown[ i] 表示第 i 天,且手里有股票(但是在冷冻期不能卖)的最大利润
42112
43113我们思考一下,其实 cooldown 这个状态数组似乎没有什么用,因为 cooldown 不会对` profit ` 产生任何影响。 我们可以进一步缩小为两种状态。
44114
45- - buy[ i] 表示第 i 天,且以 buy 或者 coolwown 结尾的最大利润
46- - sell[ i] 表示第 i 天,且以 sell 或者 cooldown 结尾的最大利润
115+ - buy[ i] 表示第 i 天,且手里有股票的最大利润
116+ - sell[ i] 表示第 i 天,且手里没股票的最大利润
47117
48118对应的状态转移方程如下:
49119
@@ -54,23 +124,27 @@ buy[i] = Math.max(buy[i - 1], sell[i - 2] - prices[i]);
54124sell[i] = Math .max (sell[i - 1 ], buy[i - 1 ] + prices[i]);
55125```
56126
57- 我们来分析一下,buy[ i] 对应第 i 的 action 只能是 buy 或者 cooldown。
127+ 我们来分析一下,buy[ i] 对应第 i 的 action 只能是 buy 或者 cooldown。(如果是 sell 的话手里就没有股票了)
58128
59129- 如果是 cooldown,那么 profit 就是 buy[ i - 1]
60130- 如果是 buy,那么就是` 前一个卖的profit减去今天买股票花的钱 ` ,即 sell[ i -2] - prices[ i]
61131
62- > 注意这里是 i - 2,不是 i-1 ,因为有 cooldown 的限制
132+ > 注意这里是 i - 2,不是 i-1 ,因为有 cooldown 一天的限制
63133
64134sell[ i] 对应第 i 的 action 只能是 sell 或者 cooldown。
65135
66- - 如果是 cooldown,那么 profit 就是 sell[ i - 1]
67- - 如果是 sell,那么就是 ` 前一次买的时候获取的利润加上这次卖的钱 ` ,即 buy[ i - 1] + prices[ i]
136+ - 如果是 cooldown,实际上就是 sell[ i - 1] 。
137+ - 如果是 sell,那么利润就是 ` 前一次买的时候获取的利润加上这次卖的钱 ` ,即 buy[ i - 1] + prices[ i]
68138
69- ## 关键点解析
139+ ### 关键点解析
70140
71141- 多状态动态规划
72142
73- ## 代码
143+ ### 代码
144+
145+ 代码支持:JS
146+
147+ JS Code:
74148
75149``` js
76150/*
@@ -110,7 +184,19 @@ var maxProfit = function (prices) {
110184};
111185```
112186
187+ ** 复杂度分析**
188+
189+ 令 n 为数组长度。
190+
191+ - 时间复杂度:$O(n)$(同上)
192+ - 空间复杂度:$O(n)$(同上)
193+
113194## 相关题目
114195
115196- [ 121.best-time-to-buy-and-sell-stock] ( ./121.best-time-to-buy-and-sell-stock.md )
116197- [ 122.best-time-to-buy-and-sell-stock-ii] ( ./122.best-time-to-buy-and-sell-stock-ii.md )
198+
199+ 力扣的小伙伴可以[ 关注我] ( https://leetcode-cn.com/u/fe-lucifer/ ) ,这样就会第一时间收到我的动态啦~
200+
201+ 以上就是本文的全部内容了, 大家对此有何看法,欢迎给我留言,我有时间都会一一查看回答。我是 lucifer,维护西湖区最好的算法题解,Github 超 40K star 。大家也可以关注我的公众号《力扣加加》带你啃下算法这块硬骨头。
202+ 另外我整理的 1000 多页的电子书已限时免费下载,大家可以去我的公众号《力扣加加》后台回复电子书获取。
0 commit comments