买卖股票重要的部分就是状态转移, 通常是二维i,0/1代表第i天持有/不持有股票时的最大利润
Part 1: 不限制交易次数
Part 2: 有交易限制
121 (一次) 一天买入, 未来一天卖出
反着遍历记录后缀最大即可
class Solution:
def maxProfit(self, prices: List[int]) -> int:
max_price = -1
ans = -1
for i in range(len(prices) - 1,-1, -1):
if prices[i] > max_price:
max_price = prices[i]
ans = max(ans, max_price - prices[i])
return ans
123 (两次)
class Solution {
public:
int maxProfit(vector<int>& prices) {
//状态有下面4种
//dp0 持有第一股 dp1卖出第一股
//dp2 持有第二股 dp3卖出第二股
//因为后一个状态是由前一天的4个状态推出来的所以可以用4个变量去维护状态
int dp0 = -prices[0], dp1 = 0, dp2 = -prices[0], dp3 = 0;
for (int i = 1; i < prices.size(); i++) {
//先用4个变量记录今天的状态
//持有第一股 维持前一天状态 今天买入(拿钱去投资了钱变少了)
int t0 = max(dp0, -prices[i]);
//不持有第一股 维持前一天状态 今天卖(前一天买入的钱+今天的钱)
int t1 = max(dp1, dp0 + prices[i]);
//持有第二股 维持前一天的状态 今天买入(第一次投资赚的 - 这次要去投资的钱)
int t2 = max(dp2, dp1 - prices[i]);
//不持有第二股 维持前一天的状态 今天卖(前一天买入的钱+今天的钱)
int t3 = max(dp3, dp2 + prices[i]);
//更新前一天状态为今天状态
dp0 = t0, dp1 = t1, dp2 = t2, dp3 = t3;
}
//肯定是卖出第二次赚的最多,因为第二次是在第一次的基础上再买卖一次
return dp3;
}
}