309. 最佳买卖股票时机含冷冻期
题目描述
给定一个整数数组prices,其中第 prices[i] 表示第 i 天的股票价格 。
设计一个算法计算出最大利润。在满足以下约束条件下,你可以尽可能地完成更多的交易(多次买卖一支股票):
卖出股票后,你无法在第二天买入股票 (即冷冻期为 1 天)。
注意:你不能同时参与多笔交易(你必须在再次购买前出售掉之前的股票)。
示例1:
输入:prices=[1,2,3,0,2]prices = [1,2,3,0,2]prices=[1,2,3,0,2]
输出:333
示例2:
输入:prices=[1]prices = [1]prices=[1]
输出:000
思路
本题最最重要的部分,就是要区分出到底有几个状态,我就是因为没分明白才不会写的。
具体可以区分出四个状态:
1、持有股票状态
今天买入股票或者之前就买入了并一直持有
2、保持卖出股票状态
两天前就已经卖出了股票,已经度过了一天的冷冻期。或者之前就已经卖出了股票并一直没有再买
3、今天卖出股票状态
今天卖出了股票,手中已经不持有股票了
4、冷冻期状态
昨天卖了股票,今天为冷冻期状态,但是需要注意的是冷冻期状态只有一天,不能持续。
递推公式的确定:
1、达到买入股票状态:
1)前一天就是持有股票状态,那么,就是不需要操作:
dp[i][0] = dp[i-1][0]
2)今日买入股票
前一天是冷冻期时,dp[i-1][3]-prices[i]
前一天是保持卖出股票状态时,dp[i-1][1]-prices[i]
2、达到保持卖出股票状态:
1)前一天是状态2:dp[i-1][1]
2)前一天是状态4:dp[i-1][3]
3、达到今天就卖出股票状态:
dp[i-1][0]+prices[i]
4、达到冷冻期状态:
dp[i-1][2]
解法1
class Solution {
public int maxProfit(int[] prices) {
if(prices == null || prices.length <2){
return 0;
}
int[][] dp = new int[prices.length][2];
dp[0][0] = 0;
dp[0][1] = -prices[0];
dp[1][0] = Math.max(dp[0][0],dp[0][1]+prices[1]);
dp[1][1] = Math.max(dp[0][1],-prices[1]);
for(int i = 2;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-2][0]-prices[i]);
}
return dp[prices.length-1][0];
}
}
解法2
class Solution {
public int maxProfit(int[] prices) {
int[][] dp = new int[prices.length+1][2];
dp[1][0] = -prices[0];
for(int i = 2;i<=prices.length;i++){
dp[i][0] = Math.max(dp[i-1][0],dp[i-2][1] - prices[i-1]);
dp[i][1] = Math.max(dp[i-1][1],dp[i-1][0] + prices[i-1]);
}
return dp[prices.length][1];
}
}
总结
本题重在能够正确划分出四个状态,并根据四种状态之间的转换来构建dp数组和状态转移方程。理解了之后可能不算太难,但是亲测如果没分好状态真的很难写出来。
714. 买卖股票的最佳时机含手续费
题目描述
给定一个整数数组 prices,其中 prices[i]表示第 i 天的股票价格 ;整数 fee 代表了交易股票的手续费用。
你可以无限次地完成交易,但是你每笔交易都需要付手续费。如果你已经购买了一个股票,在卖出它之前你就不能再继续购买股票了。
返回获得利润的最大值。
注意:这里的一笔交易指买入持有并卖出股票的整个过程,每笔交易你只需要为支付一次手续费。
示例1:
输入:prices=[1,3,2,8,4,9],fee=2prices = [1, 3, 2, 8, 4, 9], fee = 2prices=[1,3,2,8,4,9],fee=2
输出:888
示例1:
输入:prices=[1,3,7,5,10,3],fee=3prices = [1,3,7,5,10,3], fee = 3prices=[1,3,7,5,10,3],fee=3
输出:666
思路
本题就是在基础的股票上面添加了手续费,而没有其他的限制,那么就可以直接在买进或卖出的方程中除了减掉prices[i]之外一并减掉手续费即可。
解法1
class Solution {
public int maxProfit(int[] prices, int fee) {
int len = prices.length;
int[][] dp = new int[len][2];
dp[0][0] = -prices[0];
for(int i = 1;i<len;i++){
dp[i][0] = Math.max(dp[i-1][0],dp[i-1][1] - prices[i]);
dp[i][1] = Math.max(dp[i-1][0] + prices[i]-fee,dp[i-1][1]);
}
return Math.max(dp[len-1][0],dp[len-1][1]);
}
}
解法2
class Solution {
public int maxProfit(int[] prices, int fee) {
int len = prices.length;
int[][] dp = new int[len][2];
dp[0][0] = -prices[0] - fee;
for(int i = 1;i<len;i++){
dp[i][0] = Math.max(dp[i-1][0],dp[i-1][1] - prices[i] - fee);
dp[i][1] = Math.max(dp[i-1][0]+prices[i],dp[i-1][1]);
}
return Math.max(dp[len-1][0],dp[len-1][1]);
}
}
总结
基础题型上的变体,整体来说难度并不大,只需理解题意,改编基础款股票题即可。
74

被折叠的 条评论
为什么被折叠?



