leetcode刷题-动态规划08

代码随想录动态规划part08|121. 买卖股票的最佳时机、122.买卖股票的最佳时机II、123.买卖股票的最佳时机III

121.买卖股票的最佳时机

leetcode题目链接
代码随想录文档讲解

思路

本题这一只股票只买卖一次

暴力解法、动态规划解法

动态规划:

  1. dp数组的含义:
    要用二维dp数组:dpi0, dpi1分别表示持有这只股票所得的最大现金和不持有这支股票的最大现金(刚开始手里的钱数为0,那最终的钱数就是利润)。
    最终返回max(dplen(nums-1)0, dplen(nums)-11),其实是返回dplen(nums)-11,因为最后一天不持有股票手里的现金才会多
  2. 递推公式:
    a. dpi0(第i天已经持有这只股票,可能是之前就持有,也可能是今天才买入持有)
    dpi0 = max(dpi-10, -pricei) (这里负数的max就是花费最少,当前手里的现金肯定是负数)
    b. dpi1(第i天已经不持有这只股票,可能是之前就卖了,也可能是今天才卖掉这只股票)
    dpi1 = max(dpi-11, dpi-10+pricei)
    c. 思路比较不寻常,注意别想复杂了,准
  3. dp数组初始化:
    dp00 = -price0
    dp01 = 0
  4. 遍历顺序:从前往后遍历,不涉及背包中复杂的遍历顺序

python代码

python 复制代码
class Solution:
    def maxProfit(self, prices: List[int]) -> int:
        dp = [[0,0] for _ in range(len(prices)+1)]
        # dp = [[0] * 2 for _ in range(length)]
        dp[0][0] = -prices[0]
        dp[0][1] = 0
        for i in range(1, len(prices)):
            dp[i][0] = max(dp[i-1][0], -prices[i])
            dp[i][1] = max(dp[i-1][1], dp[i-1][0]+prices[i])   
        return dp[len(prices)-1][1]      

以前的提交:贪心算法

python 复制代码
class Solution:
    def maxProfit(self, prices: List[int]) -> int:
        maxprofit = 0
        mincost = 90000
        for i in range(len(prices)):
            if prices[i]<mincost:
                mincost = prices[i]
            maxprofit = max(maxprofit, prices[i]-mincost)
        return maxprofit

122.买卖股票的最佳时机II

leetcode题目链接
代码随想录文档讲解

思路

可用贪心法,本题相比上题改为:可买卖多次

贪心算法:

可买卖多次,第i天买入股票手头上的现金不是0,可能是之前买卖多次获得的利润,所以在递推公式中dpi0需要改变

dpi0 = max(dpi-10, dpi-11-pricesi)

dpi1 = max(dpi-11, dpi-10+pricesi)

python代码

python 复制代码
class Solution:
    def maxProfit(self, prices: List[int]) -> int:
        dp = [[0]*2 for _ in range(len(prices))]
        dp[0][0] = -prices[0]
        for i in range(1, len(prices)):
            dp[i][0] = max(dp[i-1][0], dp[i-1][1]-prices[i])
            dp[i][1] = max(dp[i-1][1], dp[i-1][0]+prices[i])
        return dp[len(prices)-1][1]

123.买卖股票的最佳时机III -- 困难

leetcode题目链接
代码随想录文档讲解

思路

本题最多可以完成两笔交易,不能同时参与多笔交易

  1. dp数组定义
    dpi0 不操作(没有持有过)
    dpi1 第一次持有(第一次买入或者延续了前些天买入后持有的状态)
    dpi2 第一次不持有 (已经卖出了)
    dpi3 第二次持有
    dpi4 第二次不持有
  2. 递推公式
    dpi0 = dpi-10
    dpi1 = max(dpi-11, dpi-10-pricesi)
    dpi2 = max(dpi-12, dpi-11+pricesi)
    dpi3 = max(dpi-13, dpi-12-pricesi)
    dpi4 = max(dpi-14, dpi-13+pricesi)
  3. 初始化
    dp00 = 0
    dp01 = -prices0
    dp02 = 0
    dp03 = -prices0
    dp04 = 0
  4. 遍历顺序

python代码

python 复制代码
class Solution:
    def maxProfit(self, prices: List[int]) -> int:
        dp = [[0]*5 for _ in range(len(prices))]
        dp[0][1], dp[0][3] = -prices[0], -prices[0]
        for i in range(1, len(prices)):
            dp[i][0] = dp[i-1][0]
            dp[i][1] = max(dp[i-1][1], dp[i-1][0]-prices[i])
            dp[i][2] = max(dp[i-1][2], dp[i-1][1]+prices[i])
            dp[i][3] = max(dp[i-1][3], dp[i-1][2]-prices[i])
            dp[i][4] = max(dp[i-1][4], dp[i-1][3]+prices[i])
        return dp[len(prices)-1][4] 

本题可以不用维护一个dp数组,只用4个变量即可(状态压缩)

python 复制代码
class Solution:
    def maxProfit(self, prices: List[int]) -> int:
        if len(prices) == 0:
            return 0
        dp = [0] * 5 
        dp[1] = -prices[0]
        dp[3] = -prices[0]
        for i in range(1, len(prices)):
            dp[1] = max(dp[1], dp[0] - prices[i])
            dp[2] = max(dp[2], dp[1] + prices[i])
            dp[3] = max(dp[3], dp[2] - prices[i])
            dp[4] = max(dp[4], dp[3] + prices[i])
        return dp[4]
相关推荐
a11177633 分钟前
LM 算法迭代过程动画演示(SLAM)
算法
头茬韭菜36 分钟前
Context 的生死抉择:四层压缩、截断算法与 Session Memory
算法·ai
Jerry1 小时前
LeetCode 541. 反转字符串 II
算法
Jerry1 小时前
LeetCode 344. 反转字符串
算法
搞科研的小刘选手1 小时前
【香港大学主办&IEEE出版】第六届计算机视觉、应用与算法国际学术会议(CVAA 2026)
算法·计算机视觉·应用·学术会议
Java小白笔记2 小时前
Codex config.toml配置实战指南
人工智能·算法·chatgpt·ai编程·集成学习
王老师青少年编程2 小时前
2026年6月GESP真题及题解(C++七级):消消乐
数据结构·c++·算法·真题·gesp·2026年6月
z小猫不吃鱼2 小时前
模型剪枝经典论文精读:Pruning Filters for Efficient ConvNets
算法·机器学习·剪枝
Fox爱分享4 小时前
字节二面:1000瓶酒,有一瓶是毒药,多少只老鼠可以查出来?
算法·面试·程序员
+wacyltd大模型备案算法备案4 小时前
大模型评估测试题库怎么建?风险分类、测试样本的完整方法
人工智能·算法·安全·分类·大模型·大模型备案·大模型上线登记