Day42 力扣动态规划 :123.买卖股票的最佳时机III |188.买卖股票的最佳时机IV

Day42 力扣动态规划 :123.买卖股票的最佳时机III |188.买卖股票的最佳时机IV

  • 123.买卖股票的最佳时机III
    • 第一印象
    • 看完题解的思路
      • dp数组:
      • 递推公式:
      • 初始化
      • 遍历顺序
    • 实现中的困难
    • 感悟
    • 代码
  • 188.买卖股票的最佳时机IV
    • 第一印象
    • 初始化
    • 递推公式
    • 看完题解的思路
    • 实现中的困难
    • 感悟
    • 代码

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

这道题一下子就难度上来了,关键在于至多买卖两次,这意味着可以买卖一次,可以买卖两次,也可以不买卖。
视频讲解:https://www.bilibili.com/video/BV1WG411K7AR
https://programmercarl.com/0123.%E4%B9%B0%E5%8D%96%E8%82%A1%E7%A5%A8%E7%9A%84%E6%9C%80%E4%BD%B3%E6%97%B6%E6%9C%BAIII.html

第一印象

这道题变成最多买卖两次:买卖0,1,2次都合理。

感觉挺难的,直接看题解吧。

看完题解的思路

分析一下题目里的状态,因为最多买入两次,所以有第一次的持有+不持有、第二次的持有+不持有。

在这里插入图片描述

但其实不操作这一种情况可以不管。

dp数组:

如上图所示

第 i 天在 0~4状态时,剩的最大金额是dp[i][0] ~ dp[i][4]

递推公式:

对于dp[i][1] ,第一次有股票

  • 延续前一天的第一次有股票状态:dp[i-1][1]
  • 这一天进行了买入才有股票: -price[i]

对于dp[i][2] ,第一次没有股票

  • 延续前一天的第一次没有股票的状态:dp[i-1][2]
  • 这一天进行了卖出才没有股票: dp[i-1][1] + price[i]

对于dp[i][3],第二次有股票

  • 延续前一天第二次有股票状态: dp[i-1][3]
  • 这一天进行了买入,才有股票:dp[i-1][2] - price[i]

对于dp[i][4],第二次没有股票

  • 延续了前一天第二次没有股票的状态:dp[i-1][4]
  • 这一天进行了卖出才没有股票:dp[i-1][3] + price[i]

每一次都选择更大的状态

初始化

dp[0][0] = 0
dp[0][1] = -price[I]
dp[0][2] = 0
dp[0][3] = -price[I]
dp[0][4] = 0

看做第一天买入卖出,又买入卖出

遍历顺序

正序遍历就行

实现中的困难

代码上不难

感悟

这道题我觉得难于思考的有两个地方:

  • 五种状态如何转移,在看完题解的思路那说得很清楚了
  • 如何理解初始化:第一次买卖好理解,但是第二次再买卖不怎么好理解

第二种的问题也直接导致了,这道题其实可以只买一次。**那么最后如何理解,只需要直接return dp[length][4] 。**因为它包含了买两次的,也包含了只买一次的情况。

我们手写一个只买一次的情况

在这里插入图片描述

我们会发现,每一天第一次卖出的情况是在不断更新的,第二次卖出和第一次卖出的数值也是一样的。

我觉得可能是因为初始化的时候,第二次买卖的状态就是当天买当天卖。之后这个状态一直持续在表格里。

比如2-2的位置代表,第一天买第三天卖出有最多收益,2-4的含义也是第一天买第三天卖出有最多的收益。

我认为, 它们是重复的,所以可以看作2-4 就是 2-2的当天再次买卖的情况,但本质上他们是重复的。

这里画出一个两次买卖的图就更能清晰的对比了,明白第二次买卖是怎么变的和第一次不一样的,但我懒了。

上课去咯

代码

class Solution {public int maxProfit(int[] prices) {int[][] dp = new int[prices.length][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][0] = dp[i - 1][0];dp[i][1] = Math.max(dp[i - 1][1], - 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]);}for (int i = 0; i < dp.length; i++) {for (int j = 0; j < 5; j++) {System.out.print(dp[i][j] + "  ");}System.out.println();}return dp[prices.length - 1][4];}
}

188.买卖股票的最佳时机IV

本题是123.买卖股票的最佳时机III 的进阶版
视频讲解:https://www.bilibili.com/video/BV16M411U7XJ
https://programmercarl.com/0188.%E4%B9%B0%E5%8D%96%E8%82%A1%E7%A5%A8%E7%9A%84%E6%9C%80%E4%BD%B3%E6%97%B6%E6%9C%BAIV.html

第一印象

我觉得我行

上一道题是最多 2 次买卖,就对应 第一次有、没有 + 第二次有、没有四种状态。

那么k次买卖,就对应第一次有、没有……第k次有、没有

也就是数组大小从 4 变成 2*k

然后按之前的套路去取最大值就行了。

初始化

初始化的时候有点小麻烦,因为每一次有两种状态,所以 for 循环要以 两种状态 为一次去做。就是 j += 2 而不是 j++

递推公式

递推公式也是,for 循环要以 两种状态 为一次去做。就是 j += 2 而不是 j++

这个地方需要注意!!!
对于 j = 0 的情况,如果在 i 天,计算第一次拥有的最大钱。应该是比较 i - 1天就第一次拥有的金额 和 在这一天进行第一买入的 -price[i]

因为第一次买入,不需要依赖上一天卖出的价格。

如果是计算 i 天,第三次拥有的最大钱。就是比较 i -1天就第三次拥有的金额 和 在这一天进行第三次买入的 dp[i-1][3] - price[i]

看完题解的思路

和我写的类似,他保留了 不操作 的那个状态。

实现中的困难

没有处理 j = 0的情况,就是在递推公式那里我提到的。

感悟

感觉股票问题很套路

代码

class Solution {public int maxProfit(int k, int[] prices) {//dp数组int[][] dp = new int[prices.length][2 * k];//初始化for (int j = 0; j < 2 * k; j += 2) {dp[0][j] = -prices[0];dp[0][j + 1] = 0;}//状态转移 //对于每一天来说for (int i = 1; i < prices.length; i++) {//第 j 次有股票和第j次没股票for (int j = 0; j < 2 * k; j += 2) {//第一次if (j == 0) {//昨天就有了,今天是第一次有,所以是-price[i]dp[i][j] = Math.max(dp[i - 1][j], - prices[i]);//昨天就没有、今天才没有dp[i][j + 1] = Math.max(dp[i - 1][j + 1], dp[i - 1][j] + prices[i]);} else {//昨天就有了、今天才有dp[i][j] = Math.max(dp[i - 1][j], dp[i - 1][j - 1] - prices[i]);//昨天就没有、今天才没有dp[i][j + 1] = Math.max(dp[i - 1][j + 1], dp[i - 1][j] + prices[i]);}}}return dp[prices.length - 1][2 * k - 1];}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/127260.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

react的状态管理有哪些方法?

在React中,有多种方法可以进行状态管理,以下是其中一些常见的方法: 1:使用React的内置状态(State): React组件可以通过使用 useState 钩子来管理内部的状态。它允许你在函数组件中定义和更新状态。例如: import React, { useState } from react;function MyComponent…

StringTypeHandler 是做什么的

目录 1 实现 1 实现 StringTypeHandler 是 MyBatis 框架中的一个类型处理器&#xff08;TypeHandler&#xff09;&#xff0c;用于处理 Java 类型与数据库中的字符串类型之间的转换。 在 MyBatis 中&#xff0c;当我们将 Java 对象映射到数据库表时&#xff0c;需要进行类型转…

wireshark捕获DNS

DNS解析&#xff1a; 过滤项输入dns&#xff1a; dns查询报文 应答报文&#xff1a; 事务id相同&#xff0c;flag里 QR字段1&#xff0c;表示响应&#xff0c;answers rrs变成了2. 并且响应报文多了Answers 再具体一点&#xff0c;得到解析出的ip地址&#xff08;最底下的add…

Kafka、RabbitMQ、RocketMQ中间件的对比

消息中间件现在有不少&#xff0c;网上很多文章都对其做过对比&#xff0c;在这我对其做进一步总结与整理。 RocketMQ 淘宝内部的交易系统使用了淘宝自主研发的Notify消息中间件&#xff0c;使用Mysql作为消息存储媒介&#xff0c;可完全水平扩容&#xff0c;为了进一步降低成…

35岁中年危机解决之道-技术转管理

这两年的行业对技术人员越来越不友好了&#xff0c;特别是35岁以上的技术开发人员&#xff0c;于是乎&#xff0c;很多技术路线走不上顶尖高手的技术人员纷纷选择转型项目管理&#xff0c;做项目经理。 对于大多数项目经理来说&#xff0c;他们曾经是技术专家。换句话说&#…

nacos在linux中的安装、集群的配置、mysql生产配置

1.下载和安装 官方下载地址&#xff1a;https://github.com/alibaba/nacos/releases&#xff0c;根据自己需要的本版去下载就行 下载的是 .tar.gz 后缀的文件是linux版本的 使用tar命令解压&#xff0c;完成之后是一个nacos的文件夹 和windows下的文件夹目录是一样的 要启…

SQL实现根据时间戳和增量标记IDU获取最新记录和脱IDU标记

需求说明&#xff1a;表中有 id, info, cnt 三个字段&#xff0c;对应的增量表多idu增量标记字段和时间戳字段ctimestamp。增量表中的 id 会有重复&#xff0c;其他字段 info、cnt 会不断更新&#xff0c;idu为增量标记字段&#xff0c;ctimestamp为IDU操作的时间戳。目的时要做…

汽车托运使用的场景

在托运车辆时&#xff0c;要仔细的检查车辆的性能&#xff0c;比如电瓶电量是否充足&#xff0c;发动机的性能是否良好&#xff0c;轮胎是否是正常的气压&#xff0c;冬季时需使用防冻液&#xff0c;车内禁止放易燃易爆物品。 托运时还需选择一家好的托运公司&#xff0c;首先要…

NumPy 相关函数

本篇文章介绍了Python中NumPy库的相关函数 np.corrcoef() 函数。 NumPy 中的相关性 相关系数是一个数字值&#xff0c;表示数据集给定特征之间的关系。 相关性可以是正相关&#xff0c;这意味着它们具有直接关系&#xff0c;并且一个特征的增加会导致另一个特征的增加。 负相…

创建ABAP数据库表和ABAP字典对象-创建表01

创建表 创建表在你的Package包中 选择(右键单击)包并从上下文菜单中选择New > Other ABAP Repository Object: 2.输入过滤器文本表>数据库表&#xff0c;然后选择Next。 3.输入一个名称&#xff0c;例如ZTRAINING_XXX(一般是具体的项目描述XXX)&#xff0c;然后选择Nex…

当你在浏览器地址栏输入一个URL后,将会发生的事情?个人笔记

客户端 在浏览器输入 URL 回车之后发生了什么&#xff08;超详细版&#xff09; - 知乎 (zhihu.com) 大致流程是&#xff1a; URL 解析DNS 查询TCP 连接处理请求接受响应渲染页面 1.URL解析 地址解析&#xff1a; 首先判断你输入是否是一个合法的URL还是一个待搜索的关键…

Mysql数据库学习思路

学习 MySQL&#xff08;或其他数据库管理系统&#xff09;需要一系列步骤和资源&#xff0c;以帮助您掌握数据库设计、查询语言&#xff08;SQL&#xff09;和数据库管理的基础知识。以下是一些建议的学习步骤&#xff1a; 学习数据库基础知识&#xff1a; 了解什么是数据库、数…

5.5 TCP报文段的首部格式

思维导图&#xff1a; 5.5 TCP报文段的首部格式 基本概念 TCP报文段&#xff1a;包含首部和数据两部分&#xff0c;首部至少20字节。作用&#xff1a;首部字段定义了TCP的功能和行为。长度&#xff1a;首部长度可变&#xff0c;基础首部20字节&#xff0c;可添加选项。 首部…

《算法通关村——缓存机制了解LRU实现》

《算法通关村——缓存机制了解LRU实现》 介绍 LRU是"Least Recently Used"&#xff08;最近最少使用&#xff09;的缓存机制&#xff0c;它是一种常用的缓存算法&#xff0c;用于管理缓存中的数据项。LRU缓存机制的基本思想是&#xff0c;当缓存达到其容量限制时&a…

【Tricks】PC端微信输入时,文本出现右对齐情况怎么恢复

应该是摁到某个快捷键&#xff0c;于是光标就变成如下图所示的样子&#xff1a; 如果再输入字符&#xff0c;则字符就会变成下图所示的样子&#xff08;对齐输入框右侧&#xff09;&#xff1a; 解决办法&#xff1a;ctrl J 解决办法&#xff1a;ctrl J 解决办法&#xff1…

5.2 用户数据报协议UDP

思维导图&#xff1a; 课程笔记&#xff1a;5.2 用户数据报协议UDP 5.2.1 UDP概述 一、UDP基本概念 无连接协议&#xff1a;UDP是一个简单的面向数据报的传输层协议&#xff0c;不需要在数据传输前建立连接&#xff0c;故减少开销和延迟。复用/分用&#xff1a;UDP允许多个应…

window压缩包安装mongodb并注册系统服务

下载解压包 https://fastdl.mongodb.org/windows/mongodb-windows-x86_64-5.0.22.zip启动mongod 解压压缩包 至 d:\mongodb目录中&#xff0c;创建目录data、logs。并创建配置文件mongod.conf输入以下配置 dbpath d:\mongodb\data logpath d:\mongodb\logs\mongo.log loga…

我的ChatGPT的几个使用场景

示例一&#xff0c;工作辅助、写函数代码&#xff1a; 这里展示了一个完整的代码&#xff0c;修正&#xff0c;然后最终输出的过程。GPT具备足够丰富的相关的小型代码生成能力&#xff0c;语法能力也足够好。这类应用场景&#xff0c;在我的GPT使用中&#xff0c;能占到65%以上…

PostgreSQL 特殊数据类型UUID PG_LSN

1.UUID类型 UUID&#xff08;Universally Unique Identifier&#xff09;用于存储一个UUID。 UUID定义在RFC 4122和ISO/IEC 9834-8:2005中。它是一个128bit的数 字。 [postgrespostgres ~]$ [postgrespostgres ~]$ psql psql (13.9) Type "help" for help.postgre…