leetcode刷题-动态规划08

news/2025/2/25 12:11:04

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

    • 121.买卖股票的最佳时机
    • 122.买卖股票的最佳时机II
    • 123.买卖股票的最佳时机III -- 困难

121.买卖股票的最佳时机

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

思路

本题这一只股票只买卖一次
暴力解法、动态规划解法
动态规划

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

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]      

以前的提交:贪心算法

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,可能是之前买卖多次获得的利润,所以在递推公式中dp[i][0]需要改变
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])

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数组定义
    dp[i][0] 不操作(没有持有过)
    dp[i][1] 第一次持有(第一次买入或者延续了前些天买入后持有的状态)
    dp[i][2] 第一次不持有 (已经卖出了)
    dp[i][3] 第二次持有
    dp[i][4] 第二次不持有
  2. 递推公式
    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])
  3. 初始化
    dp[0][0] = 0
    dp[0][1] = -prices[0]
    dp[0][2] = 0
    dp[0][3] = -prices[0]
    dp[0][4] = 0
  4. 遍历顺序

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个变量即可(状态压缩)

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]

http://www.niftyadmin.cn/n/5865482.html

相关文章

IOS基础面试题

1. 什么是MVC&#xff1f; MVC&#xff08;Model-View-Controller&#xff09;是一种常见的设计模式&#xff0c;用于组织代码 Model&#xff08;模型&#xff09;&#xff1a; 代表数据层&#xff0c;处理数据的逻辑。View&#xff08;视图&#xff09;&#xff1a; 负责展示…

vue2.x 中父组件通过props向子组件传递数据详细解读

1. 父组件向子组件传递数据的步骤 在子组件中定义 props&#xff1a; 子组件通过 props 选项声明它期望接收的数据。props 可以是数组形式&#xff08;简单声明&#xff09;或对象形式&#xff08;支持类型检查和默认值&#xff09;。 在父组件中使用子组件时绑定 props&#x…

Mac下VSCode调试skynet的lua环境配置

Mac下VSCode调试skynet的lua环境配置 安装Lua5.4安装Luasocket下载LuaPanda.lua安装VScode LuaPanda插件配置skynet&#xff0c;在lua_cpath引入luasocket库创建launch.json在需要调试的lua文件里面添加代码 安装Lua5.4 brew install lua5.4安装Luasocket LuaPanda需要luasoc…

IO进程 day05

IO进程 day05 9. 进程9. 9. 守护进程守护进程的特点守护进程创建步骤 10. 线程10.1. 线程的概念10.2. 进程和线程的区别10.2. 线程资源10.3. 线程的函数接口1. pthread_create-创建线程线程函数和普通函数的区别 2. pthread_exit3.线程资源回收函数join和detach的区别 获取线程…

Flink API 解析 Flink Job 依赖的checkpoint 路径

引言 之前写一篇 Python 脚本解析 Flink _metadata 中依赖的 checkpoint 路径文章 Python解析 Flink Job 依赖的checkpoint 路径 &#xff0c;代码比较暴力&#xff0c;直接按照 checkpoint 路径前缀判断&#xff0c;最近发现网上有通过 Flink API 解析 Flink Checkpoint 元数…

【JavaEE进阶】Spring Boot配置文件

欢迎关注个人主页&#xff1a;逸狼 创造不易&#xff0c;可以点点赞吗 如有错误&#xff0c;欢迎指出~ 目录 SpringBoot配置⽂件 举例: 通过配置文件修改端口号 配置⽂件的格式 properties基本语法 读取配置⽂件 properties配置文件的缺点 yml配置⽂件 yml基本语法 yml和proper…

【搭建SigNoz性能监控平台】在Ubuntu上快速搭建高效的SigNoz性能监控平台与远程使用技巧

文章目录 前言1.关于SigNoz2.本地部署SigNoz3.SigNoz简单使用4. 安装内网穿透5.配置SigNoz公网地址6. 配置固定公网地址 前言 本文介绍如何在Ubuntu系统上使用 Docker 快速部署一款强大的应用性能监控工具SigNoz&#xff0c;并结合cpolar内网穿透工具轻松实现异地远程使用。 …

插入排序:一种简单而直观的排序算法

大家好&#xff01;今天我们来聊聊一个简单却非常经典的排序算法——插入排序&#xff08;Insertion Sort&#xff09;。在所有的排序算法中&#xff0c;插入排序是最直观的一个。 一、插入排序的基本思想 插入排序的核心思想是&#xff1a;将一个待排序的元素&#xff0c;插…