思路:第二题在第一题的基础上添加了可以多次买卖这一条件,那么整体上的思路和方向是不变的,只需要在递推公式做出一点更改即可,因为推导处于持有股票状态的时候,当前的金额应该是上一次卖出股票状态下的金额,而不是0。
dp[i][0] = Math.max(dp[i-1][0],dp[i-1][1] - prices[i]);
做出此更改之后就能ac此题
class Solution {
public int maxProfit(int[] prices) {
if (prices.length == 0 || prices == null) return 0;
int[][] dp = new int[prices.length][2];
dp[0][0] = -prices[0];
dp[0][1] = 0;
for (int i = 1; i < prices.length; i++) {
// 持有股票(前一天就持有或者今天才买入 选一个最大)
dp[i][0] = Math.max(dp[i-1][0],dp[i-1][1] - prices[i]);
// 不持有(前一天就不持有或者今天才卖出 选最大的)
dp[i][1] = Math.max(dp[i-1][1],dp[i-1][0] + prices[i]);
}
return dp[prices.length -1][1];
}
}
思路:第三题比前两题都要难一些,把买卖的次数控制在两次,我们就需要去确定每一次买入卖出的状态,所以本题的dp数组应该具有五种状态, 0:无操作 1:第一次买进 2:第一次卖出 3:第二次买入 4:第二次卖出
所以需要对五种状态分别推导,在想到这里之后思路就变得清晰很多了,五种状态的推导按照前两题的思路进行分析即可
class Solution {
public int maxProfit(int[] prices) {
if (prices.length == 0 || prices == null) return 0;
// 增加状态 因为只能买进卖出两次 具体到每一次的状态 买进卖出各两次加上无操作
// 0:无操作 1:第一次买进 2:第一次卖出 3:第二次买入 4:第二次卖出
int[][] dp = new int[prices.length][5];
dp[0][0] = 0;
dp[0][1] = -prices[0];
dp[0][2] = 0;
dp[0][3] = -prices[0];
dp[0][4] = 0;
for (int i = 1; i < prices.length; i++){
dp[i][0] = dp[i-1][0];
dp[i][1] = Math.max(dp[i-1][1],dp[i-1][0] - prices[i]);
dp[i][2] = Math.max(dp[i-1][2],dp[i-1][1] + prices[i]);
dp[i][3] = Math.max(dp[i-1][3],dp[i-1][2] - prices[i]);
dp[i][4] = Math.max(dp[i-1][4],dp[i-1][3] + prices[i]);
}
return dp[prices.length - 1][4];
}
}