代码随想录训练营第50天|LeetCode 123.买卖股票的最佳时机III、188.买卖股票的最佳时机IV

news2024/11/26 18:27:05

参考

代码随想录

题目一:LeetCode 123.买卖股票的最佳时机III

  1. 确定dp数组下标及其含义
    某一天最多存在5个状态:
    • j = 0:没有操作
    • j = 1:第一次买入
    • j = 2:第一次卖出
    • j = 3:第二次买入
    • j = 4:第二次卖出

因此dp[i][j]定义为第i天j状态下所剩的最大现金。

  1. 确定递推公式
  • dp[i][0]
    第i天没有操作,那么其状态和第i-1天一样,即dp[i][0] = d0[i-1][0].
  • dp[i][1]
    注意,dp[i][1]表示的含义是第i天保持第一次买入这个状态所剩的最大现金,并不一定是第i天买入,也可能在之前就买入了。如果第i天买入,那么dp[i][1] = dp[i-1][0]-prices[i];如果在此之前就已经买入,那么dp[i][1] = dp[i-1][1]。最后要保证剩余金额最大(即买股票花费最少),因此dp[i][1] = max(dp[i-1][1],dp[i-1][0] - prices[i]).
  • dp[i][2]
    dp[i][2]表示第i天在第一次卖出这个状态下所剩余的最大现金。如果是在第i天卖出,那么dp[i][2] = dp[i-1][1] + prices[i];如果在i天之前就已经卖出,那么dp[i][2] = dp[i-1][2]。为保证利润最大,dp[i][2] = max(dp[i-1][2],dp[i-1][1] + prices[i])。
  • dp[i][3]
    dp[i][3]表示第i天保持第2次买入这个状态所剩余的最大现金。如果在第i天第二次买入,那么dp[i][3] = dp[i-1][2] - prices[i];如果在此之前已经买入,那么dp[i][3] = dp[i-1][3],为保证剩余现金最大,dp[i][3] = max(dp[i-1][3],dp[i-1][2] - prices[i])。
  • dp[i][4]
    dp[i][4]表示第i天保持第二次卖出状态下所剩余的最大现金。如果在第i天卖出,那么dp[i][4] = dp[i-1][3] + prices[i];如果在此之前已经卖出,那么dp[i][4] = dp[i-1][4]。为保证最终的利润最大,dp[i][4] = max(dp[i-1][4],dp[i-1][3] + prices[i]).

最终的递推公式为:

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]);
  1. dp数组初始化
    dp数组的第i状态只涉及到第i-1状态,因此只需要初始化i = 0的状态即可。
  • dp[0][0] = 0,第0天没有任何操作,那么剩余的现金为0,这是自定义的,可以定义任意的剩余现金,在最后计算利润的时候减去初始的剩余现金即可,如果初始化为0,最终剩余的现金就是最终利润。
  • dp[0][1] = -prices[0],第0天买入后剩余的现金就是 -prices[0],因为在上面已经初始化第0天持有的现金为0
  • dp[0][2] = 0,可以理解为第0天买入后又在第0天卖出,所以持有的剩余现金为0
  • dp[0][3] = -prices[0],第0天第二次买入,可以理解为第0天第一次买入后卖出,再买入
  • dp[0][4] = 0,第0天第一次买入再卖出,再第二次买入再卖出

总结起来,初始化如下:

dp[0][0] = 0;
dp[0][1] = -prices[0];
dp[0][2] = 0;
dp[0][3] = -prices[0];
dp[0][4] = 0;
  1. 确定遍历i顺序
    第i天的状态由第i-1天来确定,因此要从前往后遍历。

  2. 举例推导dp数组
    在这里插入图片描述
    可以看出,最后第二次卖出的利润是要大于等于第一次卖出的利润的,所以最终返回第二次卖出所得的利润即可。
    完整的代码实现如下:

class Solution {
public:
    int maxProfit(vector<int>& prices) {
        vector<vector<int>> dp(prices.size(),vector<int>(5));
        //初始化dp数组
        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 < dp.size(); i++){
            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.back()[4];
    }
};

题目二:LeetCode 188.买卖股票的最佳时机IV

这个题在上一个题的基础上加最多买卖两次变成最多买卖k次,其实求解思路是一样的,在上一个题推导递推公式的时候其实就可以发现规律了。
上一个题最多买卖两次,每天最多有5个状态,其中一个是没有操作,剩余4个是分别是每次交易的两个状态,因此很容易得到最多k次交易时,每天有2k+1个状态,其中的1是没有操作,其余每次交易都有两个状态。同样用j来标记每天的状态,当j % 2 == 1时表示当前是第j/2+1次买入状态,当j % 2 == 0时表示第j/2次卖出状态,这里当k == 2带入就是上一个题的情况了。
因此,对于最多k次交易,定义dp[i][j]:第i天时j状态下所剩余的最大现金为dp[i][j],其中0 <= j <= 2*k,当j为奇数时表示买入,当j为偶数时表示卖出。
如果是买入(j为奇数)状态,则递推公式为:

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

如果是卖出(j为偶数)状态,则递推公式为:

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

完整的代码实现如下:

class Solution {
public:
    int maxProfit(int k, vector<int>& prices) {
        vector<vector<int>> dp(prices.size(),vector<int>(2 * k + 1));
        //初始化dp数组
        for(int j = 1 ; j < 2 * k + 1; j += 2) //注意这里是j += 2
            dp[0][j] = -prices[0];  //买入状态初始化,卖出状态已经初始化为0
        //遍历
        for(int i = 1; i < dp.size(); i++){
            //dp[i][0] = dp[i-1][0];  //始终保持不变,可以不用
            for(int j = 1; j < 2 * k + 1; j += 2){      //注意这里是j += 2
                dp[i][j] = max(dp[i-1][j],dp[i-1][j-1] - prices[i]);    //买入
                dp[i][j+1] = max(dp[i-1][j+1],dp[i-1][j] + prices[i]);  //卖出
            }
        }
        return dp.back()[2*k];
    }
};

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

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

相关文章

[附源码]Python计算机毕业设计SSM基于JAVA线上订餐系统(程序+LW)

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

安卓电子名片管理器的设计与实现

毕业设计 安卓电子名片管理器的设计与实现 诚信申明 本人郑重声明&#xff1a;本设计&#xff08;论文&#xff09;及其研究工作是本人在指导教师的指导下独立完成的&#xff0c;在完成设计&#xff08;论文&#xff09;时所利用的一切资料均已在参考文献中列出。 本人签名&…

789. 数的范围

目录 题目&#xff1a;​编辑 题目思路&#xff1a; 解释&#xff1a; 方法&#xff1a; 对于k值所在左边界&#xff1a; 对于k值所在右边界&#xff1a; 代码详解&#xff1a; 题目&#xff1a; 链接&#xff1a;789. 数的范围 - AcWing题库https://www.acwing.com/prob…

【在SpringBoot项目中执行修改相册数据--MSC层】

目录 1. 编辑相册--执行修改--Mapper层 2. 编辑相册--执行修改--Service层 3. 编辑相册--执行修改--Controller层 1. 编辑相册--执行修改--Mapper层 执行修改相册使用已有的update()即可。 另外&#xff0c;还需要检查“提交修改的名称&#xff0c;是不是其它数据的名称”…

基于Pyqt5和PaddleOCR实现PDF转DOC

在上一篇文章《基于Pyqt5实现笔记本摄像头拍照及PaddleOCR测试》的基础上&#xff0c;继续做了个简单的扩展&#xff1a; 将PDF文档转换为DOC文档。 一、界面增加一个按钮&#xff0c;如下图&#xff1a; 二、源码修改 1、paddleocr.py文件直接拷贝 Github下载的源码PaddleO…

DBCO-PEG-Cholesterol,Cholesterol-PEG-DBCO,胆固醇-聚乙二醇-二苯并环辛炔

DBCO-PEG-Cholesterol属于高分子点击试剂&#xff0c;胆固醇PEG-DBCO是一种具有DBCO反应基团的亲脂性PEG衍生物。DBCO-PEG试剂在水缓冲液中具有快速动力学和稳定性&#xff0c;可用于标记具有高特异性和反应性的叠氮化物修饰的生物分子。 西安凯新生物科技有限公司​点击类化学…

写了个tooltip的切换动画,个人感觉比一些组件库的渐变动画好看

最近修改了个语言切换框的tooltip的切换动画&#xff0c;感觉比element-plus或者其他组件库的tooltip的切换动画好看一些&#xff0c;看起来比较灵动&#xff0c;下面将代码分享出来。 <!DOCTYPE html> <html lang"en"><head><meta charset&quo…

Linux内核调试技术之kprobes(1)基本原理与使用

概述 Linux kprobes技术是一种可以跟踪内核函数执行状态的轻量级内核调试技术&#xff0c;利用kprobes技术可以在运行的内核中动态的插入探测点&#xff0c;当内核运行到该探测点后可以执行用户预定义的回调函数&#xff0c;以收集所需的调试状态信息而基本不影响内核原有的执…

XXL-JOB详解(整合springboot)保姆级教程

文章目录XXL-JOB简介XXL-JOB是什么为什么需要任务调度平台&#xff0c;而不用传统的 Timer 与 Quartz为什么选择XXL-JOB&#xff0c;不选择elasticjob学习之前必看&#xff0c;少走很多弯路安装XXL-JOB一、源码编译&#xff08;Windows&#xff09;1、拉取源码&#xff1a;[xxl…

NR HARQ(二) CBG HARQ-ACK codebook

这篇开始看下HARQ-ACK codebook的相关内容&#xff0c;先看CBG-based HARQ-ACK codebook。那第一个关注点就是CBG 的划分规则&#xff0c;这部分内容主要在38.213 9.1.1章节中&#xff0c;PDSCH和PUSCH 的CBG 划分规则基本是一样的&#xff0c;这里以PDSCH为例介绍。 PDSCH 和P…

MyBatis-Plus之通用枚举

系列文章目录 Mybatis-PlusSpringBoot结合运用_心态还需努力呀的博客-CSDN博客MyBaits-Plus中TableField和TableId用法_心态还需努力呀的博客-CSDN博客 MyBatis-Plus分页查询&#xff08;快速上手运用&#xff09;_心态还需努力呀的博客-CSDN博客_mybatis plus分页查询 MyBa…

CyclicBarrier 多线程处理数据

文章目录前言需求环境准备单线程处理多线程处理总结前言 开发中&#xff0c;我们经常会遇到处理批量数据&#xff0c;最后把处理成功和失败的数据结果记录下来。普通方法一个循环就可以搞定这个需求&#xff0c;但是面临大量数据单个线程去处理可能面临很大的瓶颈&#xff0c;…

怎么进行视频配音?建议收藏这些配音方法

最近我的朋友向我求助&#xff0c;他想要自己制作一个视频&#xff0c;但是视频里面有些片段需要配音&#xff0c;可是他又不想用自己的声音来配音。一方面担心容易NG&#xff0c;需要录制很多遍&#xff0c;会浪费较多的时间&#xff1b;另一方面是&#xff0c;如果视频录制和…

​单张图像三维人脸重建必备入门face3d—3DMM

作者&#xff1a;小灰灰 来源&#xff1a;投稿 编辑&#xff1a;学姐 本次的例子是将pipeline生成的图片作用于3DMM&#xff0c;重新拟合成新的图片。 load model 3DMM的表达式&#xff1a; &#x1d446;̅ ∈ &#x1d445;3&#x1d45b;是平均人脸形状&#xff0c;&#x…

国产网关apisix安装

1、安装docker 参考&#xff1a;centos7安装docker_代码手艺人老羊的博客-CSDN博客 2、下载包&#xff08;从github&#xff09; # Download the Docker image of Apache APISIX git clone https://github.com/apache/apisix-docker.git 3、安装 # Switch the current di…

单点登录设计

01 单系统登录机制 1、http无状态协议 web应用采用browser/server架构&#xff0c;http作为通信协议。http是无状态协议&#xff0c;浏览器的每一次请求&#xff0c;服务器会独立处理&#xff0c;不与之前或之后的请求产生关联&#xff0c;这个过程用下图说明&#xff0c;三…

JavaScript高级 |彻底搞懂原型对象

本文已收录于专栏⭐️ 《JavaScript》⭐️ 学习指南&#xff1a;对象的原型函数的原型new操作符将方法放原型里constructor总结梳理原型对象内存表现完结散花参考文献对象的原型 JavaScript 当中每个对象都有一个特殊的内置属性[[prototype ]] ,这个特殊的对象可以指向另外一个…

科技云报道:畅想无人化运维的AIOps,还有多远的路要走?

科技云报道原创。 在IT行业&#xff0c;运维人常常自我调侃“赚着5k的月薪&#xff0c;操着5千万的心&#xff0c;名下挂着5亿的资产”。 机房的暖通、网络、综合布线&#xff0c;系统的监控告警、故障响应等一大堆繁杂琐碎的工作&#xff0c;充斥着运维人的日常。 与开发和产…

自定义Feign的配置

SpringBoot虽然帮我们实现了自动装配&#xff0c;但是也是支持自定义配置的。 Feign运行自定义配置来覆盖默认配置&#xff0c;可以修改的默认配置如下&#xff1a; 配置Feign日志有两种方式 方式一&#xff1a;配置文件方式 1&#xff09;全局生效 feign:client:config:defa…

【愚公系列】2022年12月 Elasticsearch数据库-ELK添加SQL插件和浏览器插件(二)

文章目录前言一、ELK添加SQL插件和浏览器插件1.配置插件2.浏览器插件3.Elasticsearch术语介绍4.测试SQL插件和浏览器插件前言 下载SQL插件地址&#xff1a;https://github.com/NLPchina/elasticsearch-sql 我们选择7.15.2版本&#xff0c;ES页选择7.15.2版本把最后面的下载链…