代码随想录算法训练营第五十一天|309.最佳买卖股票时机含冷冻期 、714.买卖股票的最佳时机含手续费

代码随想录算法训练营第五十一天|309.最佳买卖股票时机含冷冻期 、714.买卖股票的最佳时机含手续费

最佳买卖股票时机含冷冻期

309.最佳买卖股票时机含冷冻期
文章讲解: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
题目链接:https://leetcode.cn/problems/best-time-to-buy-and-sell-stock-with-cooldown/
视频讲解:https://www.bilibili.com/video/BV1rP4y1D7ku/

自己看到题目的第一想法

没想到好的处理方式。

看完代码随想录之后的想法

将当前的状态做了下拆分,整体区分出了四个状态:

  • 状态一:持有状态(今天买入,或者之前就买入了一直没操作,一直持有)
  • 不持有股票状态,这里有两种卖出股票状态
    • 状态二:保持卖出状态(两天前就卖出,度过一天冷冻期。或者是前一天就是卖出状态,一直没操作)
    • 状态三:今天卖出股票
  • 状态四:今天为冷冻期状态,但冷冻期状态不可持续,只有一天。

j的状态为:
0:状态一
1:状态二
2:状态三
3:状态四
在这里插入图片描述

自己实现过程中遇到哪些困难

看着状态转移图写的代码,但是最后返回最大值那边处理错误了,返回最大值应该是从dp[i][1-3]中取一个最大的。
还有就是Math.max最大值只能2个2个比较。
状态三和状态四不用取最大值,因为只有一个值的选择。

最终代码:

public int maxProfit(int[] prices) {
     // 确定dp数组以及下标定义,第i天最大价值
     // 确定递推公式:分四种情况,按照状态图处理
     // 1. 达到买入股票状态(状态一)之前就买入,之前是冷冻状态然后买入,之前是卖出状态再买入
     // dp[i][0] = Math.max(dp[i-1][0],dp[i-1][3]-prices[i],dp[i-1][1]-prices[i]);
     // 2. 达到保持卖出股票状态(状态二)之前就卖出,之前是冷冻状态
     // dp[i][1] = Math.max(dp[i-1][1],dp[i-1][3]);
     // 3. 达到今天就卖出股票状态(状态三)昨天买入今天卖出,
     // dp[i][2] = Math.max(dp[i-1][0] + prices[i]);
     // 4. 达到冷冻期状态(状态四)
     // dp[i][3] = Math.max(dp[i-1][2])
     int[][] dp = new int[prices.length][4];

     // 确定初始化值,第0天,只有当天买入
     dp[0][0] -= prices[0];
     dp[0][1] = 0;
     dp[0][2] = 0;
     dp[0][3] = 0;
     for(int i = 1; i < prices.length; i++){
         dp[i][0] = Math.max(dp[i-1][0],Math.max(dp[i-1][3]-prices[i],dp[i-1][1]-prices[i]));
         dp[i][1] = Math.max(dp[i-1][1],dp[i-1][3]);
         dp[i][2] = dp[i-1][0] + prices[i];
         dp[i][3] = dp[i-1][2];
     }
     return Math.max(dp[prices.length - 1][1],Math.max(dp[prices.length - 1][3],dp[prices.length - 1][2]));
 }

买卖股票的最佳时机含手续费

714.买卖股票的最佳时机含手续费
文章讲解: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://leetcode.cn/problems/best-time-to-buy-and-sell-stock-with-transaction-fee/
视频讲解:https://www.bilibili.com/video/BV1z44y1Z7UR/

自己看到题目的第一想法

看完代码随想录之后的想法

和之前的题目一样,只是在不持有状态的当天卖出再减去fee。

自己实现过程中遇到哪些困难

持有状态时的第二种情况,要用前一天不持有,前一天不持有是dp[i-1][1],而不是dp[i-1][0],同理当天要做操作时要关注到前一天的状态,用前一天的状态的值去推导。

public int maxProfit(int[] prices, int fee) {
    // 找出所有状态,状态其实和之前的一样,也只有持有和不持有
    // dp数组定义,第i天的持有/不持有状态下的最大手续费。
    int[][] dp = new int[prices.length][2];
    // 确定递推公式
    // 持有状态,不持有状态
    // 持有状态:一、前一天就持有 dp[i][0] = dp[i-1][0]; 二、前一天不持有,今天持有dp[i][0] = dp[i-1][1]- prices[i];
    // 不持有状态: 一、前一天不持有 dp[i][1] = dp[i-1][1];二、前一天持有今天卖出dp[i][1] = dp[i-1][1] + prices[i] - fee;
    dp[0][0] -= prices[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] - fee);
    }
    return Math.max(dp[prices.length - 1][1],dp[prices.length - 1][0]);
}

今日收获&学习时长

进一步深化了买卖股票题目的处理方式,整体就是按照状态去散列推导公式。

  • 9
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值