这是股票买卖系列的一道题目,这道题目的难点主要是加上了一个卖出股票的一个冷冻期,题目如下所示:
这里因为有了一个冷冻期,我们整体的解题难度就比较大了,也不好从正常的思路去解答。我们可以从动态规划的思想来解决问题。首先我们定义三个列表 sell、buy、cool,其中
s
e
l
l
[
i
]
sell[i]
sell[i] 表示截止到第 i 天,最后操作是卖的时候最大的收益;
b
u
y
[
i
]
buy[i]
buy[i] 表示截止到第 i 天, 最后操作是买的时候最大的是买的最大收益;同理
c
o
o
l
[
i
]
cool[i]
cool[i] 表示截止到第 i 天,最后操作是冷冻的最大收益。第一天的话只能不买或者做买入操作,所以
b
u
y
[
0
]
=
−
p
r
i
c
e
s
[
0
]
buy[0] = -prices[0]
buy[0]=−prices[0]。好了,定义好了初始状态之后,我们就可以开始找动态规划的递推方程。
首先是
s
e
l
l
[
i
]
sell[i]
sell[i],我们要选择合适的时候卖股票,买股票的时候我们是得到相应股票的价格的,也就是说我们需要比较当天卖股票的收益和不卖的收益,不卖的收益就是前一天的收益,所以我们取两者的最大值。可以得到递推方程:
s
e
l
l
[
i
]
=
m
a
x
(
b
u
y
[
i
−
1
]
+
p
r
i
c
e
s
[
i
]
,
s
e
l
l
[
i
−
1
]
)
sell[i] = max(buy[i-1] + prices[i], sell[i-1])
sell[i]=max(buy[i−1]+prices[i],sell[i−1])
同理,我们来找
b
u
y
[
i
]
buy[i]
buy[i],我们需要考虑当天需不需要买入股票,也就是说买的情况就是将前一个冷冻期的收益减去当前的股价,不买的情况就是前一天收益。那么可以得到递推方程:
b
u
y
[
i
]
=
m
a
x
(
c
o
o
l
[
i
−
1
]
−
p
r
i
c
e
s
[
i
]
,
b
u
y
[
i
−
1
]
)
buy[i] = max(cool[i-1] - prices[i], buy[i-1])
buy[i]=max(cool[i−1]−prices[i],buy[i−1])
然后冷冻期的递推方程比较容易理解,就是当天冷却的收益就是前一天卖出的收益。递推方程如下:
c
o
o
l
[
i
]
=
s
e
l
l
[
i
−
1
]
cool[i] = sell[i-1]
cool[i]=sell[i−1]
最后我们只需要输出卖出列表的最后一个值就行了。整个解题的代码如下所示:
class Solution(object):
def maxProfit(self, prices):
"""
:type prices: List[int]
:rtype: int
"""
n = len(prices)
if n == 0:
return 0
sell = [0 for _ in range(n)]
buy = [0 for _ in range(n)]
cool = [0 for _ in range(n)]
# 初始状态
buy[0] = -prices[0]
for i in range(1, n):
# 递推方程
sell[i] = max(buy[i-1] + prices[i], sell[i-1])
buy[i] = max(cool[i-1] - prices[i], buy[i-1])
cool[i] = sell[i-1]
# 输出卖出列表最后一个值
return sell[-1]
这道题目其实是比较复杂的,需要理清楚几种变量之间的关系,但是是很经典的一道动态规划题目,希望大家可以通过这道题目可以从整体的角度去分析题目,列出初始状态和递推方程,整个题目就可以迎刃而解了,谢谢。