一、题意
给定一个整数数组,其中第 i 个元素代表了第 i 天的股票价格 。
1、你不能同时参与多笔交易(你必须在再次购买前出售掉之前的股票)。
2、卖出股票后,你无法在第二天买入股票 (即冷冻期为 1 天)。
设计一个算法计算出最大利润。你可以尽可能地完成更多的交易(多次买卖一支股票)。
二、解法
解法:
设置三种状态:
dp[i][0]
: 代表持有股票时的最大收益。
dp[i][1]
: 没有持有股票,处于冷冻期时的最大收益。
dp[i][2]
:没有持有股票 ,没有处于冷冻期时的最大收益。
对于dp[i][0]
:可以是原来就持有股票dp[i-1][0]
或当前买入dp[i-1][2]-prices[i]
。
dp[i][0]=max(dp[i-1][0],dp[i-1][2]-prices[i])
对于dp[i][1]
:只能是当前卖出。
dp[i][1]=dp[i-1][1]+prices[i]
对于dp[i][2]
:可以是原来是冷冻期dp[i-1][1]
或没有持有股票 ,没有处于冷冻期dp[i-1][2]
。
dp[i][2]=max(dp[i][1],dp[i][2])
可以看到以上状态都是从上一次状态转移得到,可以将二维数组变成一维数组,用dp[3]
来表示三种状态。
时间复杂度:
O
(
n
)
O(n)
O(n)
空间复杂度:
O
(
1
)
O(1)
O(1)
三、代码
解法
int maxProfit(vector<int>& prices) {
int n = prices.size();
if(n==1){
return 0;
}
int dp[3];
dp[0]=-prices[0];
dp[1]=0;
dp[2]=0;
for(int i=1;i<n;i++){
int d0=dp[0],d1=dp[1],d2=dp[2];
dp[0] = max(dp[0],dp[2]-prices[i]);
dp[1] = d0+prices[i];
dp[2] =max(d1,d2);
}
return max(dp[1],dp[2]);
}
四、引用
[1] leetcode:309. Best Time to Buy and Sell Stock with Cooldown
[2] leetcode:309. Best Time to Buy and Sell Stock with Cooldown官方解法