121.买卖股票的最佳时机
贪心:
class Solution {
public:
int maxProfit(vector<int>& prices) {
int low = INT_MAX;
int result = 0;
for (int i = 0; i < prices.size(); i++) {
low = min(low, prices[i]); // 取最左最小价格
result = max(result, prices[i] - low); // 直接取最大区间利润
}
return result;
}
};
动态规划:
1.dp数组的定义–dp[i][0]表示第i天持有股票所得最多现金,dp[i][1]表示第i天不持有股票所得最多现金。注意持有不等于第i天买入。
2.递推公式:
dp[i][0] = max(dp[i - 1][0], -prices[i])第i天持有股票可能是前一天就持有股票,也可能是今天刚买的股票
dp[i][1] = max(dp[i - 1][1], prices[i] + dp[i - 1][0]);第i天不持有股票可能是昨天卖出的,也可能是今天卖出的。
3.dp数组初始化:其基础都是要从dp[0][0]和dp[0][1]推导出来。
第0天就持有股票,则就是第0天买入的。dp[0][0]=-price[0];
第0天不持有股票,则还没开始买股票,dp[0][1]=0;
4.遍历顺序:从前向后遍历。
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][1]-prices
dp[i][1]=max(dp[i-1][1],dp[i-1][0]+prices[i]);
}
return dp[prices.size()-1][1];
}
};
优化:从递推公式可以看出,dp[i]只是依赖于dp[i - 1]的状态。那么我们只需要记录 当前天的dp状态和前一天的dp状态就可以了,可以使用滚动数组来节省空间:
class Solution {
public:
int maxProfit(vector<int>& prices) {
vector<vector<int>> dp(2,vector<int>(2,0));
dp[0][0]=-prices[0];
dp[0][1]=0;
for(int i=1;i<prices.size();i++){
dp[i%2][0]=max(dp[(i-1)%2][0],-prices[i]);//dp[i-1][1]-prices
dp[i%2][1]=max(dp[(i-1)%2][1],dp[(i-1)%2][0]+prices[i]);
}
return dp[(prices.size()-1)%2][1];
}
};
买卖股票的最佳时机II
与上一道题的区别:可以多次买卖一支股票,但必须在再次购买前出售掉之前的股票
之前的贪心算法就用的这个例子讲的
这次动态规划的方法:
1.dp数组的定义:dp[i][0] 表示第i天持有股票所得现金。dp[i][1] 表示第i天不持有股票所得最多现金
2.递推公式:
dp[i][0] = max(dp[i - 1][0], dp[i-1][1]-prices[i])第i天持有股票可能是前一天就持有股票,也可能是今天刚买的股票
dp[i][1] = max(dp[i - 1][1], prices[i] + dp[i - 1][0]);第i天不持有股票可能是昨天卖出的,也可能是今天卖出的。
3.dp数组初始化:其基础都是要从dp[0][0]和dp[0][1]推导出来。
第0天就持有股票,则就是第0天买入的。dp[0][0]=-price[0];
第0天不持有股票,则还没开始买股票,dp[0][1]=0;
4.遍历顺序:从前向后遍历。
vector<vector<int>> dp(2,vector<int>(2,0));
dp[0][0]=-prices[0];
dp[0][1]=0;
for(int i=1;i<prices.size();i++){
dp[i%2][0]=max(dp[(i-1)%2][0],dp[(i-1)%2][1]-prices[i]);//dp[i-1][1]-prices
dp[i%2][1]=max(dp[(i-1)%2][1],dp[(i-1)%2][0]+prices[i]);
}
return dp[(prices.size()-1)%2][1];