第九章 动态规划part10
121. 买卖股票的最佳时机
给定一个数组 prices
,它的第 i
个元素 prices[i]
表示一支给定股票第 i
天的价格。
你只能选择 某一天 买入这只股票,并选择在 未来的某一个不同的日子 卖出该股票。设计一个算法来计算你所能获取的最大利润。
返回你可以从这笔交易中获取的最大利润。如果你不能获取任何利润,返回 0
。
思路:记录当前的最低价格,使用当前价格与最低价格之差获取当前最大利润。(使用贪心法)
class Solution {
public:
int maxProfit(vector<int>& prices) {
int min=INT_MAX;
int profit=INT_MIN;
for(int i=0;i<prices.size();i++){
if(prices[i]<=min) min=prices[i];
if(prices[i]-min>profit) profit=prices[i]-min;
}
return profit;
}
};
- 时间复杂度:O(n)
- 空间复杂度:O(1)
使用动态规划
感觉跟贪心法基本差不多,dp[i][0]其实也相当于找当前的最小买入价格,dp[i][1]则相当于找目前能够卖出的最大价格,只是采用了状态转移方式来解决。
class Solution {
public:
int maxProfit(vector<int>& prices) {
vector<vector<int>> dp(prices.size(),vector<int>(2,0));
dp[0][0]=-prices[0];
dp[0][1]=0;
for(int i=1;i<prices.size();i++){
dp[i][0]=max(dp[i-1][0],-prices[i]);
dp[i][1]=max(dp[i-1][1],prices[i]+dp[i-1][0]);
}
return dp[prices.size()-1][1];
}
};
- 时间复杂度:O(n)
- 空间复杂度:O(n)
122. 买卖股票的最佳时机 II
给你一个整数数组 prices
,其中 prices[i]
表示某支股票第 i
天的价格。
在每一天,你可以决定是否购买和/或出售股票。你在任何时候 最多 只能持有 一股 股票。你也可以先购买,然后在 同一天 出售。
返回 你能获得的 最大 利润 。
本题思路与上一题基本一致,不同之处在于递推公式:
dp含义与上一题相同:
dp[i][0]:第i天持有股票所得最多现金;
dp[i][1]:第i天不持有股票所得最多现金;
递推公式推导:
dp[i][0]:第i天持有股票由两种状态转移可以得到:
①第i-1天持有股票且第i天不卖出;
②第i-1天不持有股票且第i天买入;
dp[i][1]:第i天持有股票可有两种状态转移得到:
①第i-1天不持有股票且第i天不买入,
②第i-1天持有股票且第i天卖出。
class Solution {
public:
int maxProfit(vector<int>& prices) {
vector<vector<int>> dp(prices.size(),vector<int>(2,0));
dp[0][0]=-prices[0];
dp[0][1]=0;
for(int i=1;i<prices.size();i++){
dp[i][0]=max(dp[i-1][0],dp[i-1][1]-prices[i]);
dp[i][1]=max(dp[i-1][1],dp[i-1][0]+prices[i]);
}
return dp[prices.size()-1][1];
}
};
这两道题充分感受到了状态转移,使用动态规划一定要想好递推公式代表的是什么状态的转移。