题目来源:https://leetcode.cn/problems/best-time-to-buy-and-sell-stock-ii/description/
C++题解1:贪心算法,可以理解为找摆动序列的上升坡,然后累积坡度。
class Solution {
public:
int maxProfit(vector<int>& prices) {
int len = prices.size();
if(len == 1) return 0;
int profit = 0;
int in = 0, out = 0;
for(int i = 0; i < len-1; i++) {
if(prices[i+1] > prices[i]) {
in = prices[i];
out = prices[i+1];
while((i+2 < len)&&(prices[i+2]>prices[i+1])){
out = prices[i+2];
i++;
}
profit = profit + out - in;
}
}
return profit;
}
};
C++题解1另一种版本:在数组每次上升下降都用一个flg给予标注,每次要下降的时候就把之前的pro累积加起来,最终判断数组的尾巴是上升还是下降,上升的话pro还要计入。
class Solution {
public:
int maxProfit(vector<int>& prices) {
int n = prices.size();
if(n <= 1) return 0;
int left = prices[0];
int pro = 0, sumpro = 0;
bool flg = false; // 标记上升下降
for(int i = 1; i < n; i++){
if(prices[i] > prices[i-1]) {
flg = true; // 上升
pro = prices[i] - left; // 更新每次能获得的利益
}
else {
if(flg){ // 如果之前是上升,flg改为下降,pro累积
flg = false;
sumpro += pro;
}
left = prices[i]; // 不断更新左边最小值
}
}
if(flg) sumpro += pro; //如果最后是上升的,pro要加入和
return sumpro;
}
};
C++题解2(来源代码随想录):贪心算法,计算从第二天开始的正利润。
class Solution {
public:
int maxProfit(vector<int>& prices) {
int result = 0;
for (int i = 1; i < prices.size(); i++) {
result += max(prices[i] - prices[i - 1], 0);
}
return result;
}
};
C++题解3(来源代码随想录):动态规划
- dp[i][0] 表示第i天持有股票所得现金。
- dp[i][1] 表示第i天不持有股票所得最多现金
如果第i天持有股票即dp[i][0], 那么可以由两个状态推出来
- 第i-1天就持有股票,那么就保持现状,所得现金就是昨天持有股票的所得现金 即:dp[i - 1][0]
- 第i天买入股票,所得现金就是昨天不持有股票的所得现金减去 今天的股票价格 即:dp[i - 1][1] - prices[i]
如果第i天不持有股票即dp[i][1]的情况, 依然可以由两个状态推出来
- 第i-1天就不持有股票,那么就保持现状,所得现金就是昨天不持有股票的所得现金 即:dp[i - 1][1]
- 第i天卖出股票,所得现金就是按照今天股票价格卖出后所得现金即:prices[i] + dp[i - 1][0]
class Solution {
public:
int maxProfit(vector<int>& prices) {
int len = prices.size();
vector<vector<int>> dp(len, vector<int>(2, 0));
dp[0][0] -= prices[0];
dp[0][1] = 0;
for (int i = 1; i < len; i++) {
dp[i][0] = max(dp[i - 1][0], dp[i - 1][1] - prices[i]); // 注意这里是和121. 买卖股票的最佳时机唯一不同的地方。
dp[i][1] = max(dp[i - 1][1], dp[i - 1][0] + prices[i]);
}
return dp[len - 1][1];
}
};
滚动数组的版本
class Solution {
public:
int maxProfit(vector<int>& prices) {
int len = prices.size();
vector<vector<int>> dp(2, vector<int>(2)); // 注意这里只开辟了一个2 * 2大小的二维数组
dp[0][0] -= prices[0];
dp[0][1] = 0;
for (int i = 1; i < len; 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], prices[i] + dp[(i - 1) % 2][0]);
}
return dp[(len - 1) % 2][1];
}
};