当前位置: 首页 > news >正文

[豪の算法奇妙冒险] 代码随想录算法训练营第四十一天 | 121-买卖股票的最佳时机、122-买卖股票的最佳时机Ⅱ、123-买卖股票的最佳时机Ⅲ

代码随想录算法训练营第四十一天 | 121-买卖股票的最佳时机、122-买卖股票的最佳时机Ⅱ、123-买卖股票的最佳时机Ⅲ


LeetCode121 买卖股票的最佳时机

题目链接:https://leetcode.cn/problems/best-time-to-buy-and-sell-stock/description/

文章讲解:https://programmercarl.com/0121.买卖股票的最佳时机.html

视频讲解:

​ 动规五部曲:

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

​ dp[i][0]表示在第i天持有股票所得最多现金(初始现金为0,买入股票后为负数)

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

  1. 确定递推公式

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

  • 第 i-1 天就已持有股票,保持现状,dp[i][0] = dp[i-1][0]
  • 第 i 天买入股票,dp[i][0] = -prices[i]

​ 如果第i天未持有股票即dp[i][1],那么它可由两个状态推出:

  • 第 i-1 天未持有股票,dp[i][1] = dp[i-1][1]

  • 第 i 天卖出股票,dp[i][1] = dp[i-1][0] + prices[i]

​ 由此得到状态转移方程:

dp[i][0] = Math.max(dp[i-1][0], -prices[i]);
dp[i][1] = Math.max(dp[i-1][1], dp[i-1][0] + prices[i]);

​ 从该递推公式可看出,dp[i]只依赖于dp[i-1],因此可以使用滚动数组将二维dp进行压缩

dp[i%2][0] = Math.max(dp[(i-1)%2][0], -prices[i]);
dp[i%2][1] = Math.max(dp[(i-1)%2][1], dp[(i-1)%2][0] + prices[i]);
  1. dp数组如何初始化

​ dp[0][0] = -prices[0],第零天持有股票,那么就肯定是第零天买入了股票

​ dp[0][1] = 0,第零天未持有股票,那么就肯定是第零天未买入股票,维持初始现金0

  1. 确定遍历顺序

​ 由递推公式得出,从1开始往后顺序遍历

  1. 举例推导dp数组

class Solution {public int maxProfit(int[] prices) {if(prices.length == 1){return 0;}int[][] dp = new int[2][2];dp[0][0] = -prices[0];dp[0][1] = 0;for(int i = 1; i < prices.length; i++){dp[i%2][0] = Math.max(dp[(i-1)%2][0], -prices[i]);dp[i%2][1] = Math.max(dp[(i-1)%2][1], dp[(i-1)%2][0] + prices[i]);}return dp[(prices.length-1)%2][1];}
}

LeetCode122 买卖股票的最佳时机Ⅱ

题目链接:

文章讲解:https://programmercarl.com/0122.买卖股票的最佳时机II(动态规划).html

视频讲解:https://www.bilibili.com/video/BV1D24y1Q7Ls/?vd_source=b989f2b109eb3b17e8178154a7de7a51

​ 动规五部曲:

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

​ dp[i][0]表示在第i天持有股票所得最多现金(初始现金为0,买入股票后为负数)

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

  1. 确定递推公式

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

  • 第 i-1 天就已持有股票,保持现状,dp[i][0] = dp[i-1][0]
  • 第 i 天买入股票,所得现金就是昨日未持有-今日股价,dp[i][0] = dp[i-1][1] - prices[i]

​ 如果第i天未持有股票即dp[i][1],那么它可由两个状态推出:

  • 第 i-1 天未持有股票,dp[i][1] = dp[i-1][1]

  • 第 i 天卖出股票,所得现金就是昨日持有+今日股价,dp[i][1] = dp[i-1][0] + prices[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]);

​ 从该递推公式可看出,dp[i]只依赖于dp[i-1],因此可以使用滚动数组将二维dp进行压缩

dp[i%2][0] = Math.max(dp[(i-1)%2][0], dp[(i-1)%2][1] - prices[i]);
dp[i%2][1] = Math.max(dp[(i-1)%2][1], dp[(i-1)%2][0] + prices[i]);
  1. dp数组如何初始化

​ dp[0][0] = -prices[0],第零天持有股票,那么就肯定是第零天买入了股票

​ dp[0][1] = 0,第零天未持有股票,那么就肯定是第零天未买入股票,维持初始现金0

  1. 确定遍历顺序

​ 由递推公式得出,从1开始往后顺序遍历

  1. 举例推导dp数组

image-20260205203435807

class Solution {public int maxProfit(int[] prices) {if(prices.length == 1){return 0;}int[][] dp = new int[2][2];dp[0][0] = -prices[0];dp[0][1] = 0;for(int i = 1; i < prices.length; i++){dp[i%2][0] = Math.max(dp[(i-1)%2][0], dp[(i-1)%2][1] - prices[i]);dp[i%2][1] = Math.max(dp[(i-1)%2][1], dp[(i-1)%2][0] + prices[i]);}return dp[(prices.length-1)%2][1];}
}

LeetCode123 买卖股票的最佳时机Ⅲ

题目链接:https://leetcode.cn/problems/best-time-to-buy-and-sell-stock-iii/description/

文章讲解:https://programmercarl.com/0123.买卖股票的最佳时机III.html

视频讲解:https://www.bilibili.com/video/BV1WG411K7AR/

​ 动规五部曲:

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

​ dp[i][0]表示第i天不操作所得最大现金

​ dp[i][1]表示第i天第一次持有股票所得最大现金

​ dp[i][2]表示第i天第一次不持有股票所得最大现金

​ dp[i][3]表示第i天第二次持有股票所得最大现金

​ dp[i][4]表示第i天第二次不持有股票所得最大现金

  1. 确定递推公式

​ dp[i][0] = dp[i-1][0],第i天不操作,保持前一天的状态

​ dp[i][1] = Math.max(dp[i-1][1],dp[i-1][0] - prices[i]),之前已经买入,延续前一天的结果;第i天买入股票

​ dp[i][2] = Math.max(dp[i-1][2],dp[i-1][1] + prices[i]),前一天就已是不持有的状态,延续前一天结果/第i天卖出股票

​ dp[i][3] = Math.max(dp[i-1][3],dp[i-1][2] - prices[i]),之前已经买入,延续前一天的结果;第i天买入股票

​ dp[i][4] = Math.max(dp[i-1][4],dp[i-1][3] + prices[i]),前一天就已是不持有的状态,延续前一天结果/第i天卖出股票

​ 整理得状态转移方程:

dp[i][0] = dp[i-1][0];
dp[i][1] = Math.max(dp[i-1][1], dp[i-1][0] - prices[i]);
dp[i][2] = Math.max(dp[i-1][2], dp[i-1][1] + prices[i]);
dp[i][3] = Math.max(dp[i-1][3], dp[i-1][2] - prices[i]);
dp[i][4] = Math.max(dp[i-1][4], dp[i-1][3] + prices[i]);

​ 由递推公式可以看出,dp[i]只依赖于dp[i-1],那么可以用滚动数组将二维dp压缩:

dp[i%2][0] = dp[(i-1)%2][0];
dp[i%2][1] = Math.max(dp[(i-1)%2][1], dp[(i-1)%2][0] - prices[i]);
dp[i%2][2] = Math.max(dp[(i-1)%2][2], dp[(i-1)%2][1] + prices[i]);
dp[i%2][3] = Math.max(dp[(i-1)%2][3], dp[(i-1)%2][2] - prices[i]);
dp[i%2][4] = Math.max(dp[(i-1)%2][4], dp[(i-1)%2][3] + prices[i]);
  1. dp数组如何初始化

​ dp[0][0] = 0

​ dp[0][1] = -prices[0]、dp[0][3] = -prices[0]

​ dp[0][2] = 0、dp[0][4] = 0

  1. 确定遍历顺序

​ 由递推公式得出,从1开始往后顺序遍历

  1. 举例推导dp数组

image-20260205212716636

class Solution {public int maxProfit(int[] prices) {if(prices.length == 1){return 0;}int[][] dp = new int[2][5];dp[0][0] = 0;dp[0][1] = -prices[0];dp[0][2] = 0;dp[0][3] = -prices[0];dp[0][4] = 0;for(int i = 1; i < prices.length; i++){dp[i%2][0] = dp[(i-1)%2][0];dp[i%2][1] = Math.max(dp[(i-1)%2][1], dp[(i-1)%2][0] - prices[i]);dp[i%2][2] = Math.max(dp[(i-1)%2][2], dp[(i-1)%2][1] + prices[i]);dp[i%2][3] = Math.max(dp[(i-1)%2][3], dp[(i-1)%2][2] - prices[i]);dp[i%2][4] = Math.max(dp[(i-1)%2][4], dp[(i-1)%2][3] + prices[i]);}return dp[(prices.length-1)%2][4];}
}
http://www.jsqmd.com/news/346957/

相关文章:

  • JAVA - 并发之内存模型
  • 2026年论文降AI保姆级教程:手把手教你如何降AI,将80%的AI疑率降至5%
  • 太空生物计算融合趋势:测试从业者的新机遇
  • 2026年南京汽车租赁品牌推荐榜:轿车/包车/会议用车/旅游包车/企业用车/商务车/政企用车全方位租赁服务深度解析 - 品牌企业推荐师(官方)
  • AI驱动的星际合作协议:2026太空法下的测试从业者洞察
  • 基于深度学习的web端多格式纠错系统(源码+文档)
  • 揭秘数据库性能优化:连接池的五大核心作用
  • 生物测试架构师稀缺性危机:数据透视与行业影响
  • 2026多校冲刺省选模拟赛5
  • 为什么测试工程师更需要抗扰大脑?
  • P1429 学习笔记
  • OpenClaw+Sealos组合拳:我司的AI Agent开发效率直接翻了4倍
  • 资治通鉴-名言
  • python3.12报错:ModuleNotFoundError: No module named imp
  • ubuntu上nodejs的安装
  • 小程序开发实战:微信小程序云开发实现用户登录与数据存储
  • 别手动协调Agent了,OpenClaw的事件驱动调度让我少熬了20个夜
  • ue5 迁移 导出使用笔记
  • Spark自适应查询执行:智能优化大数据作业
  • 你能解释一下什么是JVM吗?它是如何工作的?
  • P4913 【深基16.例3】二叉树深度 dfs-二叉树的遍历
  • 未来5年IT人才需求前瞻?哪些方向爆发?哪些岗位会萎缩?程序员的职业规划重要吗?
  • 基于SpringBoot+Vue的智慧社区服务管理系统设计与实现
  • AI 这么火,.NET 开发者到底值不值得学?怎么学?
  • Trilium Demo
  • AI应用架构师经验谈:半导体研究智能体系统容错设计
  • 每日一题:中间件是如何工作的?
  • SpringDoc和Swagger运用
  • 多语言支持:构建国际化的AI Agent
  • 2-5