代码随想录算法训练营Day50动态规划:123.买卖股票的最佳时机|||,188.买卖股票的最佳时机|V

news/2025/2/12 23:08:19/

123.买卖股票的最佳时机|||(最多买卖两次股票)

文章链接:代码随想录 (programmercarl.com)

思路:难题,无思路

看完文章后的反思:依旧是遵循动规五部曲

(1)确定dp数组以及含义

一天一共就有五个状态,

  • 没有操作 (其实我们也可以不设置这个状态)
  • 第一次持有股票
  • 第一次不持有股票
  • 第二次持有股票
  • 第二次不持有股票

换言之,有如下五种状态

  • 0 表示不操作
  • 1 第一次买入
  • 2 第一次卖出
  • 3 第二次买入
  • 4 第二次卖出

dp[i][j]中 i表示第i天,j为 [0 - 4] 五个状态,dp[i][j]表示第i天状态j所剩最大现金。

需要注意:dp[i][1],表示的是第i天,买入股票的状态,并不是说一定要第i天买入股票

(2)确定递推公式

达到dp[i][1]状态,有两个具体操作:

  • 操作一:第i天买入股票了,那么dp[i][1] = dp[i-1][0] - prices[i]
  • 操作二:第i天没有操作,而是沿用前一天买入的状态,即:dp[i][1] = dp[i - 1][1]

那么dp[i][1]究竟选 dp[i-1][0] - prices[i],还是dp[i - 1][1]呢?

一定是选最大的,所以 dp[i][1] = max(dp[i-1][0] - prices[i], dp[i - 1][1]);

同理得

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

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;

第0天做第一次买入的操作,dp[0][1] = -prices[0];

第0天做第一次卖出的操作,dp[0][2] = 0;

第二次买入依赖于第一次卖出的状态,其实相当于第0天第一次买入了,第一次卖出了,然后再买入一次(第二次买入),那么现在手头上没有现金,只要买入,现金就做相应的减少。

所以第二次买入操作,初始化为:dp[0][3] = -prices[0];

同理第二次卖出初始化dp[0][4] = 0;

(4)确定遍历顺序

从前往后

(5)举例子推导

Java代码:

class Solution {public int maxProfit(int[] prices) {int len = prices.length;//(1)dp数组表示,比如dp[i][0]在第i天第1状态下所剩最大金额/** 定义 5 种状态:* 0: 没有操作, 1: 第一次买入, 2: 第一次卖出, 3: 第二次买入, 4: 第二次卖出*/int[][] dp = new int[len][5];//(2)确定递推公式// dp[i][1] = Math.max(dp[i-1][0] - prices[i], dp[i - 1][1]);// dp[i][2] = Math.max(dp[i - 1][1] + prices[i], dp[i - 1][2]);// 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]);//(3)初始化//dp[0][0] = 0; dp[0][1] = -prices[0]; dp[0][2] = 0; dp[0][3] = -prices[0]; dp[0][4] = 0;//(4)遍历顺序从前往后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 < len;i++){dp[i][1] = Math.max(dp[i-1][0] - prices[i], dp[i - 1][1]);dp[i][2] = Math.max(dp[i - 1][1] + prices[i], dp[i - 1][2]);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]);            }return dp[len - 1][4];}
}

188.买卖股票的最佳时机|V(难题)

文章链接:代码随想录 (programmercarl.com)

思路:此题更难,题目中明确了说是可以进行k次买卖股票的操作,又没有思路了

看完文章后的反思:

(1)于123题,可以发现一些规律,对于状态i来说

i的状态表示为:

  • 0 表示不操作
  • 1 第一次买入
  • 2 第一次卖出
  • 3 第二次买入
  • 4 第二次卖出
  • .....

除了0以外,偶数就是卖出,奇数就是买入,且从123题可以发现,如果最多允许买卖2次,会有5种状态,因此,如果最多允许买卖k次的话,会有2k + 1状态

(2)后面依旧遵循五部曲,只不过是在确定递推公式和初始化时需要用到for循环

Java代码:

class Solution {public int maxProfit(int k, int[] prices) {//判断特殊情况if (prices.length == 0) return 0;// (1)dp数组含义,[天数][股票状态]// 股票状态: 奇数表示第 k 次交易持有/买入, 偶数表示第 k 次交易不持有/卖出, 0 表示没有操作int len = prices.length;//最多买卖k次,有2k + 1种状态int[][] dp = new int[len][k*2 + 1];// (3)dp数组的初始化, 找规律发现,i为奇数的话为-prices[0]for (int i = 1; i < k*2; i += 2) {dp[0][i] = -prices[0];}//(4)确定遍历顺序,从前往后for (int i = 1; i < len; i++) {for (int j = 0; j < k*2 - 1; j += 2) {//(2)确定递推公式dp[i][j + 1] = Math.max(dp[i - 1][j + 1], dp[i - 1][j] - prices[i]);dp[i][j + 2] = Math.max(dp[i - 1][j + 2], dp[i - 1][j + 1] + prices[i]);}}return dp[len - 1][k*2];}
}


http://www.ppmy.cn/news/20314.html

相关文章

使用腾讯云服务器+Nonebot2+go-cqhttp搭建QQ聊天机器人

文章目录一、查看conda版本二、查看系统版本三、配置go-cqhttp1.请切换至同一网络下扫码2.打包Docker镜像四、创建NoneBot环境安装脚手架一、查看conda版本 二、查看系统版本 uname -a arch getconf LONG_BIT三、配置go-cqhttp 下载go-cqhttp 这里有不同版本的cqhttp,并且对…

Gateway服务网关

文章目录一. Gateway服务网关1. 为什么需要网关二. Gateway基本使用1. 基础搭建2. 网关路由流程图3. 路由断言工厂4. 过滤工厂1. 路由过滤种类2. 请求头过滤器5. 全局过滤器1. 全局过滤器作用2. 自定义全局过滤器6. 过滤器执行顺序7. 跨域问题解决一. Gateway服务网关 Spring …

Java基础10:常用API(下)

Java基础10&#xff1a;常用API&#xff08;下&#xff09;一、Date二、SimpleDateFormat三、Calendar四、ZoneId五、Instant六、ZoneDateTime七、DateTimeFormatter八、LocalDate、LocalTime、LocalDateTime九、Duration、Period、ChronoUnit十、包装类一、Date Date类是一个…

初识图像分类——K近邻法(cs231n assignment)

作者&#xff1a;非妃是公主 专栏&#xff1a;《计算机视觉》 个性签&#xff1a;顺境不惰&#xff0c;逆境不馁&#xff0c;以心制境&#xff0c;万事可成。——曾国藩 专栏系列文章 Cannot find reference ‘imread‘ in ‘init.py‘ error: (-209:Sizes of input arguments…

自动驾驶感知——视觉感知经典算法

文章目录1. 车道线检测技术1.1 基于规则的车道线检测技术1.1.1 流程框架1.1.2 预处理模块1.1.3 车道线识别感兴趣区域提取1.1.4 灰度图转化1.1.5 灰度图去噪1.1.6 二值化操作1.1.7 鲁棒性参数估计——RANSAC1.1.8 后处理模块1.1.9 输出1.2 车道线检测技术发展路线2. 目标检测技…

教育数字化转型 看低代码怎么构建实现

数字经济和数字社会的发展&#xff0c;推动教育培养目标和内容的发展与变革。经过教育信息化1.0和2.0的建设&#xff0c;我国数字技术与教育经历了起步、应用、融合、创新四个阶段&#xff0c;目前正处于融合与创新并存的时期。教育数字化教育数字化转型是教育信息化的特殊阶段…

MYSQL中常见的知识问题(二)

1、B树和B树的区别&#xff0c;MYSQL为啥使用B树。 1.1、B树 目的&#xff1a;为了存储设备或者磁盘设计的一种平衡查找树。 定义&#xff08;M阶B树&#xff09;&#xff1a;a、树中的每个节点最多有m个孩子。 b、除了根节点和叶子节点外&#xff0c;其他节点最少含有m/2(取上…

CF449D: Jzzhu and Numbers

CF449D: Jzzhu and Numbers 原题链接:https://codeforces.com/problemset/problem/449/D 题解 记 cvc_vcv​ 为 [aiv][a_iv][ai​v] 的个数&#xff0c; NNN 为二进制位数。 设 fSf_SfS​ 表示位与和在二进制下包含 SSS 的子集数。 由定义易得: fS2∑S⊆TcTf_S2^{\sum\limit…