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


    文档讲解:代码随想录

    视频讲解:代码随想录B站账号

    状态:看了视频题解和文章解析后做出来了

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

    1. class Solution:
    2. def maxProfit(self, prices: List[int]) -> int:
    3. n = len(prices)
    4. if n < 2:
    5. return 0
    6. dp = [[0]*3 for _ in range(len(prices))]
    7. dp[0][0] = -prices[0]
    8. for i in range(1, len(prices)):
    9. dp[i][0] = max(dp[i-1][0], dp[i-1][2] - prices[i])
    10. dp[i][1] = dp[i-1][0] + prices[i]
    11. dp[i][2] = max(dp[i-1][2], dp[i-1][1])
    12. return max(dp[-1][1], dp[-1][2])
    • 时间复杂度:O(n)
    • 空间复杂度:O(n)

    1. 确定dp数组以及下标的含义

    这道题引入了冷冻期的概念,也就是卖出以后有一天不能交易。

    这里需要定义三个状态:

    (1)状态0:持有股票

    (2)状态1:不持有股票且进入冷冻期

    (3)状态2:不持有股票且不在冷冻期

    2. 确定递推公式

    - 状态0的持有股票有两种情况,第一种是延续昨天持有的状态,第二种是今天买了股票:

    dp[i][0] = max(dp[i-1][0], dp[i-1][2] - prices[i]),注意买股票沿用的昨天不在冷冻期的状态,如果昨天进入了冷冻期那今天就不能买股票了。

    - 状态1只有一种情况,也就是昨天持有股票今天卖了并进入冷冻期

    dp[i][1] = dp[i-1][0] + prices[i]

    - 状态2有两种情况,延续之前的不持有股票状态和刚从冷冻期解冻且不买股票。

    dp[i][2] = max(dp[i-1][1], dp[i-1][2])

    3. dp数组的初始化

    只有状态0需要初始化为-prices[i],因为状态0是第一天就持有股票。

    4. 遍历顺序

    递推公式中有i-1,所以从前往后遍历

    5. dp数组举例

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

    1. class Solution:
    2. def maxProfit(self, prices: List[int], fee: int) -> int:
    3. if len(prices) == 0:
    4. return 0
    5. dp = [[0]*2 for _ in range(len(prices))]
    6. dp[0][0] = -prices[0]
    7. for i in range(1, len(prices)):
    8. dp[i][0] = max(dp[i-1][0], dp[i-1][1] - prices[i])
    9. dp[i][1] = max(dp[i-1][1], dp[i-1][0] + prices[i] - fee)
    10. return dp[-1][1]
    • 时间复杂度:O(n)
    • 空间复杂度:O(n)

    和最常规的买卖股票题的唯一区别就是加了一个手续费,只有在卖出的时候减去手续费fee即可。

    唯一差别在于递推公式部分,所以本篇也就不按照动规五部曲详细讲解了,主要讲解一下递推公式部分。

    这里重申一下dp数组的含义:

    dp[i][0] 表示第i天持有股票所省最多现金。 dp[i][1] 表示第i天不持有股票所得最多现金

    如果第i天持有股票即dp[i][0], 那么可以由两个状态推出来

    • 第i-1天就持有股票,那么就保持现状,所得现金就是昨天持有股票的所得现金 即:dp[i - 1][0]
    • 第i天买入股票,所得现金就是昨天不持有股票的所得现金减去 今天的股票价格 即:dp[i - 1][1] - prices[i]

    所以:dp[i][0] = max(dp[i - 1][0], dp[i - 1][1] - prices[i]);

    在来看看如果第i天不持有股票即dp[i][1]的情况, 依然可以由两个状态推出来

    • 第i-1天就不持有股票,那么就保持现状,所得现金就是昨天不持有股票的所得现金 即:dp[i - 1][1]
    • 第i天卖出股票,所得现金就是按照今天股票价格卖出后所得现金,注意这里需要有手续费了即:dp[i - 1][0] + prices[i] - fee

    所以:dp[i][1] = max(dp[i - 1][1], dp[i - 1][0] + prices[i] - fee);

    最后返回的是最后一天不持有股票时候的现金数。

     

  • 相关阅读:
    吸烟检测Y8N,支持C++,PYTHON,ANDROID
    微服务(十二)——Steam消息驱动&Sleuth链路监控
    使用 shell 脚本自动申请进京证 (六环外) —— debug 过程
    【Vision Pro应用】分享一个收集Apple Vision Pro 应用的网站
    大饼简记.
    记录--怎么实现一个3d翻书效果
    MySQL之DML操作
    从0开始C++(五):友元函数&运算符重载
    微服务实践k8s&dapr开发部署实验(3)订阅发布
    [100天算法】-键值映射(day 42)
  • 原文地址:https://blog.csdn.net/Dork_41/article/details/134543430