第九章 动态规划part12
● 309.最佳买卖股票时机含冷冻期
● 714.买卖股票的最佳时机含手续费
●总结
309.最佳买卖股票时机含冷冻期
本题加了一个冷冻期,状态就多了,有点难度,大家要把各个状态分清,思路才能清晰
视频讲解:https://www.bilibili.com/video/BV1rP4y1D7ku
https://programmercarl.com/0309.%E6%9C%80%E4%BD%B3%E4%B9%B0%E5%8D%96%E8%82%A1%E7%A5%A8%E6%97%B6%E6%9C%BA%E5%90%AB%E5%86%B7%E5%86%BB%E6%9C%9F.html
714.买卖股票的最佳时机含手续费
相对122.买卖股票的最佳时机II ,本题只需要在计算卖出操作的时候减去手续费就可以了,代码几乎是一样的,可以尝试自己做一做。
视频讲解:https://www.bilibili.com/video/BV1z44y1Z7UR
https://programmercarl.com/0714.%E4%B9%B0%E5%8D%96%E8%82%A1%E7%A5%A8%E7%9A%84%E6%9C%80%E4%BD%B3%E6%97%B6%E6%9C%BA%E5%90%AB%E6%89%8B%E7%BB%AD%E8%B4%B9%EF%BC%88%E5%8A%A8%E6%80%81%E8%A7%84%E5%88%92%EF%BC%89.html
股票总结
股票问题做一个总结吧
https://programmercarl.com/%E5%8A%A8%E6%80%81%E8%A7%84%E5%88%92-%E8%82%A1%E7%A5%A8%E9%97%AE%E9%A2%98%E6%80%BB%E7%BB%93%E7%AF%87.html
往日任务
● day 1 任务以及具体安排:https://docs.qq.com/doc/DUG9UR2ZUc3BjRUdY
● day 2 任务以及具体安排:https://docs.qq.com/doc/DUGRwWXNOVEpyaVpG
● day 3 任务以及具体安排:https://docs.qq.com/doc/DUGdqYWNYeGhlaVR6
● day 4 任务以及具体安排:https://docs.qq.com/doc/DUFNjYUxYRHRVWklp
● day 5 周日休息
● day 6 任务以及具体安排:https://docs.qq.com/doc/DUEtFSGdreWRuR2p4
● day 7 任务以及具体安排:https://docs.qq.com/doc/DUElCb1NyTVpXa0Jj
● day 8 任务以及具体安排:https://docs.qq.com/doc/DUGdsY2JFaFhDRVZH
● day 9 任务以及具体安排:https://docs.qq.com/doc/DUHVXSnZNaXpVUHN4
● day 10 任务以及具体安排:https://docs.qq.com/doc/DUElqeHh3cndDbW1Q
●day 11 任务以及具体安排:https://docs.qq.com/doc/DUHh6UE5hUUZOZUd0
●day 12 周日休息
●day 13 任务以及具体安排:https://docs.qq.com/doc/DUHNpa3F4b2dMUWJ3
●day 14 任务以及具体安排:https://docs.qq.com/doc/DUHRtdXZZSWFkeGdE
●day 15 任务以及具体安排:https://docs.qq.com/doc/DUHN0ZVJuRmVYeWNv
●day 16 任务以及具体安排:https://docs.qq.com/doc/DUHBQRm1aSWR4T2NK
●day 17 任务以及具体安排:https://docs.qq.com/doc/DUFpXY3hBZkpabWFY
●day 18 任务以及具体安排:https://docs.qq.com/doc/DUFFiVHl3YVlReVlr
●day 19 周日休息
●day 20 任务以及具体安排:https://docs.qq.com/doc/DUGFRU2V6Z1F4alBH
●day 21 任务以及具体安排:https://docs.qq.com/doc/DUHl2SGNvZmxqZm1X
●day 22 任务以及具体安排:https://docs.qq.com/doc/DUHplVUp5YnN1bnBL
●day 23 任务以及具体安排:https://docs.qq.com/doc/DUFBUQmxpQU1pa29C
●day 24 任务以及具体安排:https://docs.qq.com/doc/DUEhsb0pUUm1WT2NP
●day 25 任务以及具体安排:https://docs.qq.com/doc/DUExTYXVzU1BiU2Zl
●day 26 休息
●day 27 任务以及具体安排:https://docs.qq.com/doc/DUElpbnNUR3hIbXlY
●day 28 任务以及具体安排:https://docs.qq.com/doc/DUG1yVHdlWEdNYlhZ
●day 29 任务以及具体安排:https://docs.qq.com/doc/DUHZYbWhwSHRCRmp3
●day 30 任务以及具体安排:https://docs.qq.com/doc/DUEdTVVhxbnJiY3BR
●day 31 任务以及具体安排:https://docs.qq.com/doc/DUG1PQ1ZZY2xXY1ly
●day 32 任务以及具体安排:https://docs.qq.com/doc/DUGFEdGFWeVhleFF1
●day 33 周日休息
●day 34 任务以及具体安排:https://docs.qq.com/doc/DUEh5WFVlQkp1U0p4
●day 35 任务以及具体安排:https://docs.qq.com/doc/DUFRWc3BGRHFXZ1pO
●day 36 任务以及具体安排:https://docs.qq.com/doc/DUERGbnhhRkFRVENZ
●day 37 任务以及具体安排:https://docs.qq.com/doc/DUFVRd3p5SHFMSExQ
●day 38 任务以及具体安排:https://docs.qq.com/doc/DUGNUdVpoT0VJR01l
●day 39 任务以及具体安排:https://docs.qq.com/doc/DUE55cVJ5WkNoREhS
●day 40 周日休息
●day 41 任务以及具体安排:https://docs.qq.com/doc/DUFhIUXRFYnVGUkFp
●day 42 任务以及具体安排:42 第八章 动态规划
●day 43 任务以及具体安排:43第八章 动态规划
●day 44 任务以及具体安排:44 第八章 动态规划
●day 45 任务以及具体安排:45 第八章 动态规划
●day 46 任务以及具体安排:46 第八章 动态规划
●day 47 周日休息
●day 48 任务以及具体安排:48 第八章 动态规划
●day 49 任务以及具体安排:49 第八章 动态规划
●day 50 任务以及具体安排:50 第八章 动态规划
目录
0309_最佳买卖股票时机含冷冻期
package com.question.solve.leetcode.programmerCarl2._10_dynamicProgramming;
public class _0309_最佳买卖股票时机含冷冻期 {
}
class Solution0309 {
public int maxProfit(int[] prices) {
if (prices == null || prices.length < 2) {
return 0;
}
int[][] dp = new int[prices.length][2];
//bad case
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公式
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];
}
}
//这里稍微说一下,我在LeetCode提交的时候,2*4 2-D array的性能performance基本上和下面的1-D array performance性能差不多
//都是time: 1ms, space: 40.X MB (其实 length*4 的 2-D array也仅仅是space:41.X MB,看起来不多)
//股票类的DP题目大致上都是这样,就当作是一个延伸就好了。真的有人问如何优化,最起码有东西可以讲。
class Solution0309_2 {
/**
* 1. [i][0] holding the stock
* 2. [i][1] after cooldown but stil not buing the stock
* 3. [i][2] selling the stock
* 4. [i][3] cooldown
*/
public int maxProfit(int[] prices) {
int len = prices.length;
int dp[][] = new int[2][4];
dp[0][0] = -prices[0];
for (int i = 1; i < len; i++) {
dp[i % 2][0] = Math.max(Math.max(dp[(i - 1) % 2][0], dp[(i - 1) % 2][1] - prices[i]), dp[(i - 1) % 2][3] - prices[i]);
dp[i % 2][1] = Math.max(dp[(i - 1) % 2][1], dp[(i - 1) % 2][3]);
dp[i % 2][2] = dp[(i - 1) % 2][0] + prices[i];
dp[i % 2][3] = dp[(i - 1) % 2][2];
}
return Math.max(Math.max(dp[(len - 1) % 2][1], dp[(len - 1) % 2][2]), dp[(len - 1) % 2][3]);
}
}
class Solution0309_3 {//一维数组优化
public int maxProfit(int[] prices) {
int[] dp = new int[4];
dp[0] = -prices[0];
dp[1] = 0;
for (int i = 1; i <= prices.length; i++) {
//使用临时变量来保存dp[0], dp[2]
//因为马上dp[0]和dp[2]的数据都会变
int temp = dp[0];
int temp1 = dp[2];
dp[0] = Math.max(dp[0], Math.max(dp[3], dp[1]) - prices[i]);
dp[1] = Math.max(dp[1], dp[3]);
dp[2] = temp + prices[i];
dp[3] = temp1;
}
return Math.max(dp[3], Math.max(dp[1], dp[2]));
}
}
class Solution0309_4 {//另一种解题思路
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] 第i天持有股票收益;
dp[i][1] 第i天不持有股票收益;
情况一:第i天是冷静期,不能以dp[i-1][1]购买股票,所以以dp[i - 2][1]买股票,没问题
情况二:第i天不是冷静期,理论上应该以dp[i-1][1]购买股票,但是第i天不是冷静期说明,第i-1天没有卖出股票,
则dp[i-1][1]=dp[i-2][1],所以可以用dp[i-2][1]买股票,没问题
*/
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];
}
}
0714_买卖股票的最佳时机含手续费
package com.question.solve.leetcode.programmerCarl2._10_dynamicProgramming;
public class _0714_买卖股票的最佳时机含手续费 {
}
class Solution0714 {
/**
* 卖出时支付手续费
*
* @param prices
* @param fee
* @return
*/
public int maxProfit(int[] prices, int fee) {
int len = prices.length;
//0 : 持股(买入)
//1 : 不持股(售出)
//dp 定义第i天持股/不持股 所得最多现金
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]);
}
/**
* 买入时支付手续费
*
* @param prices
* @param fee
* @return
*/
public int maxProfit2(int[] prices, int fee) {
int len = prices.length;
//0 : 持股(买入)
//1 : 不持股(售出)
//dp 定义第i天持股/不持股 所得最多现金
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]);
}
}
class Solution0714_2 {//一维数组优化
public int maxProfit(int[] prices, int fee) {
int[] dp = new int[2];
dp[0] = -prices[0];
dp[1] = 0;
for (int i = 1; i <= prices.length; i++) {
dp[0] = Math.max(dp[0], dp[1] - prices[i - 1]);
dp[1] = Math.max(dp[1], dp[0] + prices[i - 1] - fee);
}
return dp[1];
}
}
class Solution0714_3 {//使用 2*2 array
public int maxProfit(int[] prices, int fee) {
int dp[][] = new int[2][2];
int len = prices.length;
//[i][0] = holding the stock
//[i][1] = not holding the stock
dp[0][0] = -prices[0];
for (int i = 1; i < len; i++) {
dp[i % 2][0] = Math.max(dp[(i - 1) % 2][0], dp[(i - 1) % 2][1] - prices[i]);
dp[i % 2][1] = Math.max(dp[(i - 1) % 2][1], dp[(i - 1) % 2][0] + prices[i] - fee);
}
return dp[(len - 1) % 2][1];
}
}
文章评论