121. 买卖股票的最佳时机
给定一个数组
prices
,它的第i
个元素prices[i]
表示一支给定股票第i
天的价格。你只能选择 某一天 买入这只股票,并选择在 未来的某一个不同的日子 卖出该股票。设计一个算法来计算你所能获取的最大利润。
返回你可以从这笔交易中获取的最大利润。如果你不能获取任何利润,返回
0
。
输入:[7,1,5,3,6,4]
输出:5
解释:在第 2 天(股票价格 = 1)的时候买入,在第 5 天(股票价格 = 6)的时候卖出,最大利润 = 6-1 = 5 。
注意利润不能是 7-1 = 6, 因为卖出价格需要大于买入价格;同时,你不能在买入前卖出股票。
动规五部曲:
- 确定dp及其下标含义
dp[i][0]表示第i天持有股票所得的最多现金
dp[i][1]表示第i天不持有股票的最多现金
- 确定递推公式
如果第i天持有股票dp[i][0],那么可以由两个状态推导出来
第i-1天就持有股票,第i天保持现状:dp[i-1][0]
第i天买入股票,所得现金就是今天买入后所得的现金:-prices[i]
如果第i天不持有股票dp[i][1],那么可以由两个状态推导出来
第i-1天就不持有股票,第i天保持现状:dp[i-1][1]
第i天卖出股票,所得现金就是今天卖出的价钱:prices[i]+dp[i-1][0]
综上,递推公式为:
dp[i][0]=Math.max(dp[i-1][0],-prices[i]);
dp[i][1]=Math.max(dp[i-1][1],(prices[i]+dp[i-1][0]));
- dp数组初始化
dp[0][0]=-prices[0]
dp[0][1]=0;
- 确定遍历顺序
dp[i]需要依靠dp[i-1]推导出来,所以需要从前向后遍历
- 举例推导dp数组
prices=[7 1 5 3 6 4]
dp[i][0]=[-7 -1 -1 -1 -1 -1]
dp[i][1]=[0 0 4 4 5 5]
所以最终结果为dp[5][1]
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],-prices[i]);
dp[i][1]=Math.max(dp[i-1][1],(prices[i]+dp[i-1][0]));
}
return dp[prices.length-1][1];
}
}
122. 买卖股票的最佳时机 II
给你一个整数数组
prices
,其中prices[i]
表示某支股票第i
天的价格。在每一天,你可以决定是否购买和/或出售股票。你在任何时候 最多 只能持有 一股 股票。你也可以先购买,然后在 同一天 出售。
返回 你能获得的 最大 利润 。
输入:prices = [7,1,5,3,6,4]
输出:7
解释:在第 2 天(股票价格 = 1)的时候买入,在第 3 天(股票价格 = 5)的时候卖出, 这笔交易所能获得利润 = 5 - 1 = 4 。
随后,在第 4 天(股票价格 = 3)的时候买入,在第 5 天(股票价格 = 6)的时候卖出, 这笔交易所能获得利润 = 6 - 3 = 3 。
总利润为 4 + 3 = 7 。
之前用贪心做过这道题,只需要考虑正区间就可以了,此处利用动规考虑问题。
动规五部曲:
- 确定dp以及下标含义
dp[i][0]表示第i天不持有股票时的最大利润
dp[i][1]表示第i天持有股票的最大利润
- 确定递推公式
第i天不持有股票
第i-1天就不持有股票,i天保持:dp[i-1][0]
第i-1天持有股票,第i天不持有股票:dp[i-1][1]+prices[i]
第i天持有股票
第i-1天就持有股票,第i天保持:dp[i-1][1]
第i-1天不持有股票,第i天持有股票:dp[i-1][0]-prices[i]
- dp数组初始化
dp[0][0]=0;
dp[0][1]=-prices[0];
- 确定遍历顺序
dp[i]需要由dp[i-1]确定,所以从前向后遍历
- 举例推导dp数组
prices=[7 1 5 3 6 4]
dp[i][0]=[0 0 4 4 7 7]
dp[i][1]=[-7 -1 -1 1 1 3]
dp[5][0]=7;
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]=0;
dp[0][1]=-prices[0];
for(int i=1;i<prices.length;i++){
//第i天不持有股票
dp[i][0]=Math.max(dp[i-1][0],dp[i-1][1]+prices[i]);
//第i天持有股票
dp[i][1]=Math.max(dp[i-1][1],dp[i-1][0]-prices[i]);
}
return dp[prices.length-1][0];
}
}