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

news2025/2/25 12:01:46

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.coloradmin.cn/o/1158873.html

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

相关文章

黄金矿工小游戏

欢迎来到程序小院 黄金矿工 玩法&#xff1a;点击开始游戏&#xff0c;黄金和钩子&#xff0c;钩子会左右摆动&#xff0c;对准黄金位置点击鼠标左键钓起黄金加对应时间&#xff0c;钓起黑色四块减去响应时间&#xff0c;快去挖矿吧^^。开始游戏https://www.ormcc.com/play/ga…

【错误解决方案】Error: module ‘cv2‘ has no attribute ‘SURF‘

1. 错误提示 python-opencv高版本中&#xff0c;AttributeError: module cv2 has no attribute SURF问题&#xff1b; 错误提示&#xff1a;Error: module ‘cv2‘ has no attribute ‘SURF‘ 2. 解决方案 解决&#xff1a;将sift cv2.SIFT()替换为&#xff1a;sift cv2.x…

windows内存取证-中等难度-下篇

上文我们对第一台Target机器进行内存取证&#xff0c;今天我们继续往下学习&#xff0c;内存镜像请从上篇获取&#xff0c;这里不再进行赘述​ Gideon 攻击者访问了“Gideon”&#xff0c;他们向AllSafeCyberSec域控制器窃取文件,他们使用的密码是什么&#xff1f; 攻击者执…

day57--动态规划15

392.判断子序列 115.不同的子序列 第一题&#xff1a;判断子序列 给定字符串 s 和 t &#xff0c;判断 s 是否为 t 的子序列。 字符串的一个子序列是原始字符串删除一些&#xff08;也可以不删除&#xff09;字符而不改变剩余字符相对位置形成的新字符串。&#xff08;例如&…

大模型冷思考:企业“可控”价值创造空间还有多少?

文 | 智能相对论 作者 | 叶远风 毫无疑问&#xff0c;大模型热潮正一浪高过一浪。 在发展进程上&#xff0c;从最开始的技术比拼到现在已开始全面强调商业价值变现&#xff0c;百度、科大讯飞等厂商都喊出类似“不能落地的大模型没有意义”等口号。 在模型类型上&#xff0…

2023年【高压电工】考试及高压电工找解析

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 高压电工考试参考答案及高压电工考试试题解析是安全生产模拟考试一点通题库老师及高压电工操作证已考过的学员汇总&#xff0c;相对有效帮助高压电工找解析学员顺利通过考试。 1、【单选题】 额定容量是指:在变压器铭…

Spring源码分析篇:@Autowired 是怎样完成注入的?究竟是byType还是byName亦两者皆有

1. 五种不同场景下 Autowired 的使用 第一种情况 上下文中只有一个同类型的bean 配置类 package org.example.bean; ​ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; ​ Configuration public class…

docker-compose 简单部署MySQL Database

docker-compose 简单部署MySQL Database 本博文部署MySQL 并与上篇部署的 Flask进行关联 主博客目录&#xff1a;《从零开始学习搭建量化平台笔记》 文章目录 docker-compose 简单部署MySQL Database部署 MySQLMySQL 开放端口与权限 主项目计划需要搭建一个MySQL 数据库为其他部…

“零基础”PHP代码审计入门

目录 一、代码审计目的 二、代码审计基础 三、 代码审计思路 四、PHP核心配置 五、 代码审计环境 六、手动调试代码 七、PHP的弱类型 八、学习漏洞函数 九、审计入门总结 推荐一些demo&#xff1a; 一、代码审计目的 代码审计指的是对源代码进行检查&#xff0c;寻找…

智慧校园地下管线三维可视化管控平台减少人力和物力资源的浪费

随着科技的不断发展&#xff0c;三维可视化管理平台在各个领域得到了广泛的应用。三维可视化管理平台通过将数据以三维形式呈现&#xff0c;使得用户能够更直观地理解和分析数据&#xff0c;从而提高工作效率和决策质量。 VR数字孪生园区系统是通过将实际园区的各种数据和信息进…

开关电源老化试验和性能检测系统软件

开关电源自动测试系统由PC(工控机)、测试工装、可编程直流电源、数字示波器、可编程直流电子负载、继电器模块等部分组成&#xff0c;并通过RS232/LAN通讯总线、测试夹具以及其它线缆等进行连接&#xff0c;为系统组成结构。PC与可编程直流电源、数字示波器、可编程直流电子负载…

c++装饰器模式

前言 装饰器模式&#xff0c;就是可以对一个对象无限装饰一些东西&#xff0c;而且可以没有顺序。比如一个人可能只会说出他的名字&#xff0c;但是可以让他再说哈哈&#xff0c;可以说完哈哈之后再说哇哇。如何后面又不想装饰了&#xff0c;不需要改类原来的代码&#xff0c;…

什么是数字展览馆,数字展览馆有什么应用前景

引言&#xff1a; 数字展览馆作为一种新兴的文化艺术展示形式&#xff0c;以数字化技术和虚拟现实为基础&#xff0c;正在逐渐改变传统展览的方式。 一、什么是数字展览馆&#xff1f; 1.定义 数字展览馆是利用数字技术和虚拟现实技术打造的一种线上文化艺术展示平台。通过虚…

基于springboot实现疫情防控期间外出务工人员信息管理系统项目【项目源码+论文说明】计算机毕业设计

基于springboot疫情防控期间外出务工人员信息管理系统 摘要 网络的广泛应用给生活带来了十分的便利。所以把疫情防控期间某村外出务工人员信息管理与现在网络相结合&#xff0c;利用java技术建设疫情防控期间某村外出务工人员信息管理系统&#xff0c;实现疫情防控期间某村外出…

《完蛋!我被美女包围了》突然火了!世界首个开源贡献榜出炉丨 RTE 开发者日报 Vol.75

开发者朋友们大家好&#xff1a; 这里是 「RTE 开发者日报」 &#xff0c;每天和大家一起看新闻、聊八卦。我们的社区编辑团队会整理分享 RTE &#xff08;Real Time Engagement&#xff09; 领域内「有话题的 新闻 」、「有态度的 观点 」、「有意思的 数据 」、「有思考的 文…

我的天!阿里云服务器居然比腾讯云优惠1元!

2023阿里云服务器优惠活动来了&#xff0c;以前一直是腾讯云比阿里云优惠&#xff0c;阿里云绝地反击&#xff0c;放开老用户购买资格&#xff0c;99元服务器老用户可以买&#xff0c;并且享受99元续费&#xff0c;阿腾云亲测可行&#xff0c;大家抓紧吧&#xff0c;数量不多&a…

Mac上的iTerm2和Oh My Zsh 的安装(安装过程和失败详解)

前言&#xff08;无重点&#xff0c;安装往后看&#xff09; 由于在很多人的安利下&#xff0c;说很好用&#xff0c;作者今天花费了4个小时用血的教训总结出来的安装教程&#xff0c;我在安装过程中遇到的最大的问题就是 1. curl: (7) Failed to connect to raw.githubusercon…

电影《河边的错误》观后感

上周看了电影《河边的错误》&#xff0c;整部电影看介绍&#xff0c;是改编余华的小说&#xff0c;并且获得多种奖项&#xff0c;一般来说&#xff0c;差不了&#xff0c;看完之后&#xff0c;只能说&#xff0c;看得有些云里雾里的&#xff0c;看似最后主角抓到了罪犯&#xf…

STM32循迹小车原理介绍和代码示例

目录 1. 循迹模块介绍 2. 循迹小车原理 3. 循迹小车核心代码 4. 循迹小车解决转弯平滑问题 1. 循迹模块介绍 TCRT5000传感器的红外发射二极管不断发射红外线当发射出的红外线没有被反射回来或被反射回来但强度不够大时红外接收管一直处于关断状态&#xff0c;此时模块的输出…

被这7款在线涂鸦画板惊艳到,手残也能画出涂鸦大片!

作为一名涂鸦爱好者或者手帐达人&#xff0c;你是否在寻找好用的在线涂鸦画板软件呢&#xff1f;涂鸦画板软件释放了创造性的无限可能&#xff0c;让你能够将想法转化为令人惊叹的视觉效果&#xff0c;并轻松地与客户、同行和全球观众分享你的作品。 在这篇文章中&#xff0c;…