解题思路
这是一道最多可以进行两次股票交易的问题,主要思路如下:
- 状态定义:
- h0s0[i]: 第i天结束时,无股票且卖出0次的最大收益
- h1s0[i]: 第i天结束时,持有1股且卖出0次的最大收益
- h0s1[i]: 第i天结束时,无股票且卖出1次的最大收益
- h1s1[i]: 第i天结束时,持有1股且卖出1次的最大收益
代码
class Solution {
public:
/**
* 计算你能获得的最大收益
* @param prices Prices[i]即第i天的股价
* @return 整型
*/
int calculateMax(vector<int> prices) {
int n = prices.size();
if(n < 2) return 0;
if(n == 2) return max(0, prices[1] - prices[0]);
// 定义四种状态数组
vector<int> h0s0(n), h1s0(n), h0s1(n), h1s1(n);
// 初始化状态
h0s0[0] = 0; // 无股票,未卖出
h1s0[0] = -prices[0]; // 有1股,未卖出
h0s1[1] = prices[1] - prices[0]; // 无股票,卖出1次
h1s1[2] = -prices[2] + prices[1] - prices[0]; // 有1股,卖出1次
int res = 0;
for(int i = 1; i < n; i++) {
// 状态转移
h0s0[i] = h0s0[i-1]; // 保持无股票无卖出
h1s0[i] = max(h1s0[i-1], h0s0[i-1] - prices[i]); // 保持或买入
h0s1[i] = max(h0s1[i-1], h1s0[i-1] + prices[i]); // 保持或卖出第一次
res = max(res, h0s1[i]);
if(i >= 3) {
h1s1[i] = max(h1s1[i-1], h0s1[i-1] - prices[i]); // 保持或第二次买入
res = max(res, h1s1[i-1] + prices[i]); // 考虑第二次卖出
}
}
return res;
}
};
public class Solution {
/**
* 计算你能获得的最大收益
* @param prices Prices[i]即第i天的股价
* @return 整型
*/
public int calculateMax(int[] prices) {
int n = prices.length;
if(n < 2) return 0;
if(n == 2) return Math.max(0, prices[1] - prices[0]);
// 定义四种状态数组
int[] h0s0 = new int[n];
int[] h1s0 = new int[n];
int[] h0s1 = new int[n];
int[] h1s1 = new int[n];
// 初始化状态
h0s0[0] = 0;
h1s0[0] = -prices[0];
h0s1[1] = prices[1] - prices[0];
h1s1[2] = -prices[2] + prices[1] - prices[0];
int res = 0;
for(int i = 1; i < n; i++) {
// 状态转移
h0s0[i] = h0s0[i-1];
h1s0[i] = Math.max(h1s0[i-1], h0s0[i-1] - prices[i]);
h0s1[i] = Math.max(h0s1[i-1], h1s0[i-1] + prices[i]);
res = Math.max(res, h0s1[i]);
if(i >= 3) {
h1s1[i] = Math.max(h1s1[i-1], h0s1[i-1] - prices[i]);
res = Math.max(res, h1s1[i-1] + prices[i]);
}
}
return res;
}
}
算法及复杂度
- 算法:动态规划
- 时间复杂度:
- 需要遍历一次数组
- 空间复杂度:
- 需要4个长度为
的数组存储状态