LeetCode解题 309:Best Time to Buy and Sell Stock with Cooldown (动态规划)
Problem 309: Best Time to Buy and Sell Stock with Cooldown [Medium]
Say you have an array for which the ith element is the price of a given stock on day i.
Design an algorithm to find the maximum profit. You may complete as many transactions as you like (ie, buy one and sell one share of the stock multiple times) with the following restrictions:
- You may not engage in multiple transactions at the same time (ie, you must sell the stock before you buy again).
- After you sell your stock, you cannot buy stock on next day. (ie, cooldown 1 day)
Example:
Input: [1,2,3,0,2]
Output: 3
Explanation: transactions = [buy, sell, cooldown, buy, sell]
来源:LeetCode
解题思路
本题仍然需要使用动态规划思想。与题解188:Best Time to Buy and Sell Stock IV同属于最佳时机买卖股票问题。
解题思路与之前不同的是,不再使用minCost和maxP的思路,而是直接使用maxP的状态转移方程,每天的maxP分为两种:maxP0和maxP1,分别代表当天不持有股票和当天持有股票的最大利润。本题中在买操作之前有一个冷却期,因此第i天的maxP0可以由第i-1天的maxP0和maxP1转移,而第i天的maxP1则由第i-1天的maxP1和第i-2天的maxP0转移。这是由于第i天买入股票的前提条件是在第i-2天之前已经卖出,而不能在i-1天才卖出,所以无法由第i-1天的maxP0转移至第i天的maxP1。
状态转移方程为:
m
a
x
P
0
[
i
]
=
max
{
m
a
x
P
0
[
i
−
1
]
,
m
a
x
P
1
[
i
−
1
]
+
p
r
i
c
e
s
[
i
]
}
m
a
x
P
1
[
i
]
=
max
{
m
a
x
P
1
[
i
−
1
]
,
m
a
x
P
0
[
i
−
2
]
−
p
r
i
c
e
s
[
i
]
}
maxP_0[i] = \max\{maxP_0[i-1], maxP_1[i-1] + prices[i]\} \\ maxP_1[i] = \max\{maxP_1[i-1], maxP_0[i-2] - prices[i]\}
maxP0[i]=max{maxP0[i−1],maxP1[i−1]+prices[i]}maxP1[i]=max{maxP1[i−1],maxP0[i−2]−prices[i]}
其中,
m
a
x
P
1
[
i
−
1
]
+
p
r
i
c
e
s
[
i
]
maxP_1[i-1] + prices[i]
maxP1[i−1]+prices[i]的意思是第i-1天持有的股票在当前天卖出;
m
a
x
P
0
[
i
−
2
]
−
p
r
i
c
e
s
[
i
]
maxP_0[i-2] - prices[i]
maxP0[i−2]−prices[i]的意思是第i-2天之前卖出的股票在当前天买入。
由于maxP0更新只使用到前一天的maxP0和maxP1,maxP1更新也只使用到前一天的maxP1和再前一天的maxP0,因此可以不使用maxP0[N]和maxP1[N]来存储,只需使用常数空间。
状态转移更新为:
m
a
x
P
0
=
max
{
m
a
x
P
0
,
m
a
x
P
1
+
p
r
i
c
e
s
[
i
]
}
m
a
x
P
1
=
max
{
m
a
x
P
1
,
p
r
e
m
a
x
P
0
−
p
r
i
c
e
s
[
i
]
}
maxP_0 = \max\{maxP_0, maxP_1 + prices[i]\} \\ maxP_1 = \max\{maxP_1, premaxP_0 - prices[i]\}
maxP0=max{maxP0,maxP1+prices[i]}maxP1=max{maxP1,premaxP0−prices[i]}
其中,
m
a
x
P
0
maxP_0
maxP0初始化为0,
m
a
x
P
1
maxP_1
maxP1初始化为-prices[0],
p
r
e
m
a
x
P
0
premaxP_0
premaxP0指i-2天的
m
a
x
P
0
maxP_0
maxP0。
该方法时间复杂度为 O ( n ) O(n) O(n),空间复杂度为 O ( 1 ) O(1) O(1)。
运行结果:
要点:动态规划
Solution (Java)
class Solution {
public int maxProfit(int[] prices) {
int N = prices.length;
if(N < 2) return 0;
int minCost = prices[0];
int[] maxP = new int[N];
int maxP0 = 0;
int maxP1 = -prices[0];
int pre_maxP0 = 0;
int temp;
for(int i = 1; i < N; i++){
temp = maxP0;
maxP0 = Math.max(maxP0, maxP1 + prices[i]);
maxP1 = Math.max(maxP1, pre_maxP0 - prices[i]);
pre_maxP0 = temp;
}
return maxP0;
}
}
修改过程
- 一开始pre_maxP0采样先进先出队列,但是提交后发现运行时间需要2ms,后修改为两个变量temp和pre_maxP0。