https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock-iii/
解法1:动态规划
1.dp[i][k]表示第i天交易k次所能获得的最大利润
dp[i][k]有两种操作可以求出来,1.第i天什么都不做,那么dp[i][k]=dp[i-1][k].2.第i天选择卖出,既然选择了卖出,那么0-i-1天就要选择一天进行买入,且在买入前已经进行了k-1次交易。
我们用mins表示第1天到第i天prices[buy]-dp[buy][k-1]的最小值,(这样我们便能取得第i天卖出的最大利润)
然后比较dp[i-1][k]和prices[i]-mins,选择第i天到达进行什么操作
其中mins=min(mins,prices[i]-dp[i][k-1])
dp[i][k]=max(dp[i-1][k],prices[i]-mins)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| class Solution { public: int maxProfit(vector<int>& prices) { int n=prices.size(); if(n==0) return 0; vector<vector<int>> dp(n,vector<int>(3,0)); for(int k=1;k<=2;k++) { int mins=prices[0]; for(int i=1;i<n;i++) { mins=min(mins,prices[i]-dp[i][k-1]); dp[i][k]=max(dp[i-1][k],prices[i]-mins); } } return dp[n-1][2]; } };
|
解法2:优化时间复杂度
上面一种解法先将k放在外循环,i放在内循环,我们也可以对换位置,只要将mins赋对应初值即可
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| class Solution { public: int maxProfit(vector<int>& prices) { int n=prices.size(); if(n==0) return 0; vector<int> dp(3,0); int mins[3]; mins[0]=prices[0]; mins[1]=prices[0]; mins[2]=prices[0]; for(int i=1;i<n;i++) { for(int k=1;k<=2;k++) { mins[k]=min(mins[k],prices[i]-dp[k-1]); dp[k]=max(dp[k],prices[i]-mins[k]); } } return dp[2]; } };
|
解法3:优化空间复杂度
上面的方法用了O(n)的空间复杂度,分析发现我们可以用O(1)的空间复杂度
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| class Solution { public: int maxProfit(vector<int>& prices) { int n=prices.size(); if(n==0) return 0; int min1=prices[0],min2=prices[0]; int dp1=0,dp2=0; for(int i=1;i<n;i++) { min1=min(min1,prices[i]-0); dp1=max(dp1,prices[i]-min1); min2=min(min2,prices[i]-dp1); dp2=max(dp2,prices[i]-min2); } return dp2; } };
|