【LeetCode-122】买卖股票的最佳时机 II
问题
给定一个数组,它的第 i 个元素是一支给定股票第 i 天的价格。
设计一个算法来计算你所能获取的最大利润。你可以尽可能地完成更多的交易(多次买卖一支股票)。
注意:你不能同时参与多笔交易(你必须在再次购买前出售掉之前的股票)。
示例
输入: [7,1,5,3,6,4]
输出: 7
解答1:完整状态机
class Solution {
public:
int maxProfit(vector<int>& prices) {
int n = prices.size();
vector<int> hold(n + 1, INT_MIN);
vector<int> sold(n + 1, 0);
for (int i = 1; i <= n; i++) {
sold[i] = max(sold[i - 1], hold[i - 1] + prices[i - 1]);
hold[i] = max(hold[i - 1], sold[i - 1] - prices[i - 1]);
}
return sold[n];
}
};
重点思路
分析思路同【LeetCode-188】买卖股票的最佳时机 IV,由于本题不限制k
,所以只需要去掉这一个维度即可。
解答2:状态压缩
class Solution {
public:
int maxProfit(vector<int>& prices) {
int sold = 0, hold = INT_MIN;
for (int p : prices) {
sold = max(sold, hold + p);
hold = max(hold, sold - p);
}
return sold;
}
};
重点思路
观察可知,sold
和hold
在状态转移时都只需要前一天的状态,所以我们只需要暂存前一天的状态即可将空间复杂度压缩为常数空间,具体来讲,我们只需要暂存sold[i - 1]
。
进一步分析,当sold[i - 1] >= hold[i - 1] + p
时,此时sold[i] = sold[i - 1]
;当sold[i - 1] < hold[i - 1] + p
时,hold[i - 1] > sold[i - 1] - p
,此时hold[i] = hold[i - 1]
。可以看出,我们并不需要暂存sold[i - 1]
,因为求hold[i]
时,要么用不上sold[i - 1]
,要么此时sold[i] == sold[i - 1]
。
解答3:贪心算法
class Solution {
public:
int maxProfit(vector<int>& prices) {
int res = 0;
for (int i = 1; i < prices.size(); i++) {
int diff = prices[i] - prices[i - 1];
if (diff > 0) res += diff;
}
return res;
}
};
重点思路
既然可以不限次数且无手续费,那么当明天价格比今天高时,就今天买明天卖,是一种贪心思想。