123. 买卖股票的最佳时机 III
给定一个数组,它的第 **
i
个元素是一支给定的股票在第i
**天的价格。设计一个算法来计算你所能获取的最大利润。你最多可以完成 两笔 交易。
**注意:**你不能同时参与多笔交易(你必须在再次购买前出售掉之前的股票)。
输入:prices = [3,3,5,0,0,3,1,4]
输出:6
解释:在第 4 天(股票价格 = 0)的时候买入,在第 6 天(股票价格 = 3)的时候卖出,这笔交易所能获得利润 = 3-0 = 3 。
随后,在第 7 天(股票价格 = 1)的时候买入,在第 8 天 (股票价格 = 4)的时候卖出,这笔交易所能获得利润 = 4-1 = 3 。
按照题目描述每天的操作状态可以分为五个状态
0:没有操作
1:第一天持有股票
2:第一天不持有股票
3:第二天持有股票
4:第二天不持有股票
动规五部曲:
- 确定dp数组及其下标含义
dp[i][j]表示第i天的0-4个中的j状态下最大金额
- 确定递推公式
dp[i][1]的状态下有两种可能:
第i天买入股票:dp[i][1]=dp[i-1][0]-prices[i]
第i-1天买入股票,第i天保持:dp[i][1]=dp[i-1][1]
综上,dp[i][1]=max(dp[i-1][0]-prices[i],dp[i][1]=dp[i-1][1] )
dp[i][2]的状态下有两种可能:
第i天不持有股票:dp[i][2]=dp[i-1][1]+prices[i];
第i-1天不持有,第i天保持:dp[i][2]=dp[i-1][2];
综上,dp[i][2]=max(dp[i][2]=dp[i-1][1]+prices[i], dp[i][2]=dp[i-1][2])
dp[i][3]=max(dp[i-1][3],dp[i-1][2]-prices[i]);
dp[i][4]=max(dp[i-1][4],dp[i-1][3]+prices[0]);
- dp数组初始化
dp[0][1]=-prices[0]
dp[0][3]=-prices[0]
其他下标被设置为0即可
- 确定遍历顺序
因为后一个状态需要由前一个状态推导得出,所以需要从前向后遍历
-
举例推导dp数组
prices=[1 2 3 4 5]
dp[i][0]=[0 0 0 0 0]
dp[i][1]=[-1 -1 -1 -1 -1]
dp[i][2]=[0 1 2 3 4]
dp[i][3]=[-1 -1 -1 -1 -1]
dp[i][4]=[0 1 2 3 4]
class Solution {
public int maxProfit(int[] prices) {
if(prices==null||prices.length==0){
return 0;
}
int[][] dp=new int[prices.length][5];
dp[0][1