leetcode买卖股票的最佳时机系列共6题:
买卖股票的最佳时机:只能交易一次
买卖股票的最佳时机Ⅱ:可交易无限次
买卖股票的最佳时机Ⅲ:最多交易2次
买卖股票的最佳时机Ⅳ:最多交易k次
含冷冻期:卖掉之后隔一天才能买
含手续费:买入时交手续费
状态转移图如下:
dp[i][k][0] = max(dp[i-1][k][0], dp[i-1][k][1] + prices[i])
max( 选择 rest , 选择 sell )
解释:今天我没有持有股票,有两种可能:
要么是我昨天就没有持有,然后今天选择 rest,所以我今天还是没有持有;
要么是我昨天持有股票,但是今天我 sell 了,所以我今天没有持有股票了。
dp[i][k][1] = max(dp[i-1][k][1], dp[i-1][k-1][0] - prices[i])
max( 选择 rest , 选择 buy )
解释:今天我持有着股票,有两种可能:
要么我昨天就持有着股票,然后今天选择 rest,所以我今天还持有着股票;
要么我昨天本没有持有,但今天我选择 buy,所以今天我就持有股票了。
再根据不同题目的情况处理basecase即可(i=0和k=0的情况)
- 第一题:k=1
public int maxProfit(int[] prices) {
int n = prices.length;//由于每次跟新只需要相邻的数据,降低空间复杂度
int dp_i_0 = 0, dp_i_1 = Integer.MIN_VALUE;
for(int i=0;i<n;i++){
dp_i_0 = Math.max(dp_i_0, dp_i_1+prices[i]);
dp_i_1 = Math.max(dp_i_1, 0-prices[i]);
}
return dp_i_0;
}
- 第二提:k无限
public int maxProfit(int[] prices) {
int n = prices.length; //方法一:动态规划,使用二维数组
int[][] dp = new int[n][2];
for(int i=0;i<n;i++){
if(i==0){
dp[0][0] = 0;
dp[0][1] = -prices[0];//第一次买入
continue;