代码随想录算法训练营第五十一天|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]);
}

今日收获&学习时长

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

相关推荐

最近更新

  1. TCP协议是安全的吗?

    2024-01-13 20:26:03       18 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-01-13 20:26:03       19 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-01-13 20:26:03       18 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-01-13 20:26:03       20 阅读

热门阅读

  1. python爬虫,发送请求需要携带cookies

    2024-01-13 20:26:03       39 阅读
  2. 允许一切发生

    2024-01-13 20:26:03       35 阅读
  3. 【重点!!!】【DP】354. 俄罗斯套娃信封问题

    2024-01-13 20:26:03       41 阅读
  4. 第十讲_css2d转换

    2024-01-13 20:26:03       43 阅读
  5. Rust 宏的使用

    2024-01-13 20:26:03       39 阅读
  6. 一体机旅游景区污水处理设备工艺说明

    2024-01-13 20:26:03       41 阅读
  7. SpringBoot ObjectMapper 返回json 指定字段排序

    2024-01-13 20:26:03       45 阅读