买卖股票的最佳时机
可以用贪心算法来解决。也就是从左向右维护股票价格的最小值,从而可以得到最大的利润。
class Solution {
public:
int maxProfit(vector<int>& prices) {
int min_value = INT_MAX;
int result = 0;
for(int i = 0; i < prices.size(); i++) {
min_value = min(min_value, prices[i]);
result = max(result, prices[i] - min_value);
}
return result;
}
};
动态规划思路,dp数组的含义感觉不好想。dp[i][0] 表示第 i+1 天持有股票能获得的最大利润,dp[i][1] 表示第 i+1 天不持有股票能获得的最大利润。
对于递推公式,第 i+1 天持有股票可以分为之前就持有股票维持状态 dp[i-1][0],以及当天买入股票 -prices[i]。第 i+1 天不持有股票可以分为之前就不持有股票维持状态 dp[i-1][1],以及当天卖出持有的股票 dp[i-1][0]+prices[i]。
class Solution {
public:
int maxProfit(vector<int>& prices) {
int len = prices.size();
vector<vector<int>> dp(2, vector<int>(2, 0));
dp[0][0] = -prices[0]; // 0-持有股票,1-不持有股票
dp[0][1] = 0;
for(int i = 1; i < len; i++) {
dp[i % 2][0] = max(dp[(i - 1) % 2][0], -prices[i]);
dp[i % 2][1] = max(dp[(i - 1) % 2][1], dp[(i - 1) % 2][0] + prices[i]);
}
return dp[(len - 1) % 2][1];
}
};
买卖股票的最佳时机II
在贪心算法中利用总利润是可分解的思路来执行贪心策略。下面是动态规划的思路,类似于上一道题。需要注意这里股票可以买很多次,所以dp[i][0] = max(dp[i - 1][0], dp[i - 1][1] - prices[i])
,这与上道题的dp[i][0] = max(dp[i - 1][0], -prices[i])
不同。
class Solution {
public:
int maxProfit(vector<int>& prices) {
int n = prices.size();
vector<vector<int>> dp(2, vector<int>(2, 0));
dp[0][0] = -prices[0]; // 0-持有股票的最大收益
dp[0][1] = 0; // 1-不持有股票的最大收益
for(int i = 1; i < n; i++) {
dp[i % 2][0] = max(dp[(i - 1) % 2][0], dp[(i - 1) % 2][1] - prices[i]);
dp[i % 2][1] = max(dp[(i - 1) % 2][1], dp[(i - 1) % 2][0] + prices[i]);
}
return dp[(n - 1) % 2][1];
}
};