题目:
题解:动态规划
代码:动态规划
1. 代码一:常规代码
public class code309 {
public static int maxProfit(int[] prices) {
if(prices.length == 0)
{
return 0;
}
int n = prices.length;
// dp[i][0]: 手上持有股票的最大收益
// dp[i][1]: 手上不持有股票,并且处于冷冻期中的累计最大收益
// dp[i][2]: 手上不持有股票,并且不在冷冻期中的累计最大收益
int dp[][] = new int[n][3];
dp[0][0] = -prices[0];
for(int i = 1; i < n; i++)
{
// 对于 dp[i][0],我们目前持有的这一支股票可以是在第 i-1 天就已经持有的,对应的状态为 dp[i-1][0];
// 或者是第 i 天买入的,那么第 i-1 天就不能持有股票并且不处于冷冻期中,对应的状态为 dp[i-1][2] 加上买入股票的负收益 prices[i]。
dp[i][0] = Math.max(dp[i - 1][0], dp[i - 1][2] - prices[i]);
// 对于 dp[i][1],我们在第 i 天结束之后处于冷冻期的原因是在当天卖出了股票,那么说明在第 i-1 天时我们必须持有一支股票,
// 对应的状态为 dp[i-1][0] 加上卖出股票的正收益 prices[i]。
dp[i][1] = dp[i - 1][0] + prices[i];
// 对于 dp[i][2],我们在第 i 天结束之后不持有任何股票并且不处于冷冻期,说明当天没有进行任何操作,即第 i−1 天时不持有任何股票:
// 如果处于冷冻期,对应的状态为 dp[i-1][1];如果不处于冷冻期,对应的状态为 dp[i-1][2]。
dp[i][2] = Math.max(dp[i - 1][1], dp[i - 1][2]);
}
// 如果在最后一天(第 n-1 天)结束之后,手上仍然持有股票,那么显然是没有任何意义的。
// 因此更加精确地,最终的答案实际上是 dp[n-1][1] 和 dp[n-1][2] 中的较大值。
return Math.max(dp[n - 1][1], dp[n - 1][2]);
}
public static void main(String[] args) {
int prices[] = { 1, 2, 3, 0, 2 };
int res = maxProfit(prices);
System.out.println(res);
}
}
2. 代码二:空间优化
class Solution {
public int maxProfit(int[] prices) {
if (prices.length == 0) {
return 0;
}
int n = prices.length;
int f0 = -prices[0];
int f1 = 0;
int f2 = 0;
for (int i = 1; i < n; ++i) {
int newf0 = Math.max(f0, f2 - prices[i]);
int newf1 = f0 + prices[i];
int newf2 = Math.max(f1, f2);
f0 = newf0;
f1 = newf1;
f2 = newf2;
}
return Math.max(f1, f2);
}
}