代码随想录算法训练营day50|123.买卖股票的最佳时机III|188.买卖股票的最佳时机IV

news2024/12/24 16:12:59

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

力扣题目链接

给定一个数组,它的第 i 个元素是一支给定的股票在第 i 天的价格。

设计一个算法来计算你所能获取的最大利润。你最多可以完成 两笔 交易。

注意:你不能同时参与多笔交易(你必须在再次购买前出售掉之前的股票)。

  • 示例 1:
  • 输入:prices = [3,3,5,0,0,3,1,4]
  • 输出:6 解释:在第 4 天(股票价格 = 0)的时候买入,在第 6 天(股票价格 = 3)的时候卖出,这笔交易所能获得利润 = 3-0 = 3 。随后,在第 7 天(股票价格 = 1)的时候买入,在第 8 天 (股票价格 = 4)的时候卖出,这笔交易所能获得利润 = 4-1 = 3。
  • 示例 2:
  • 输入:prices = [1,2,3,4,5]
  • 输出:4 解释:在第 1 天(股票价格 = 1)的时候买入,在第 5 天 (股票价格 = 5)的时候卖出, 这笔交易所能获得利润 = 5-1 = 4。注意你不能在第 1 天和第 2 天接连购买股票,之后再将它们卖出。因为这样属于同时参与了多笔交易,你必须在再次购买前出售掉之前的股票。
  • 示例 3:
  • 输入:prices = [7,6,4,3,1]
  • 输出:0 解释:在这个情况下, 没有交易完成, 所以最大利润为0。
  • 示例 4:
  • 输入:prices = [1] 输出:0

提示:

  • 1 <= prices.length <= 10^5

  • 0 <= prices[i] <= 10^5

  • 动态规划

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

1——第一次持有股票

2——第一次不持有股票

3——第二次持有股票

4——第二次不持有股票

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

2.确定递推公式

持有操作

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

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

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

不持有操作

dp[i][2]也有两个操作:

  • 操作一:第i天卖出股票了,那么dp[i][2] = dp[i - 1][1] + prices[i]
  • 操作二:第i天没有操作,沿用前一天卖出股票的状态,即:dp[i][2] = dp[i - 1][2]

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

3.初始化

第0天没有操作,这个最容易想到,就是0,即:dp[0][0] = 0;

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

第0天做第一次卖出,当天买入,当天卖出,所以dp[0][2] = 0;

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

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

4.遍历顺序

前向后

5.打印dp数组

以输入[1,2,3,4,5]为例

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

大家可以看到红色框为最后两次卖出的状态。

现在最大的时候一定是卖出的状态,而两次卖出的状态现金最大一定是最后一次卖出。如果想不明白的录友也可以这么理解:如果第一次卖出已经是最大值了,那么我们可以在当天立刻买入再立刻卖出。所以dp[4][4]已经包含了dp[4][2]的情况。也就是说第二次卖出手里所剩的钱一定是最多的。

所以最终最大利润是dp[4][4]

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][1]=Math.max(dp[i-1][1],dp[i-1][0]-prices[i]);
            dp[i][3]=Math.max(dp[i-1][3],dp[i-1][2]-prices[i]);
            dp[i][2]=Math.max(dp[i-1][2],dp[i-1][1]+prices[i]);
            dp[i][4]=Math.max(dp[i-1][4],dp[i-1][3]+prices[i]);
        }
        return dp[prices.length-1][4];
    }
}

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

力扣题目链接

给定一个整数数组 prices ,它的第 i 个元素 prices[i] 是一支给定的股票在第 i 天的价格。

设计一个算法来计算你所能获取的最大利润。你最多可以完成 k 笔交易。

注意:你不能同时参与多笔交易(你必须在再次购买前出售掉之前的股票)。

  • 示例 1:
  • 输入:k = 2, prices = [2,4,1]
  • 输出:2 解释:在第 1 天 (股票价格 = 2) 的时候买入,在第 2 天 (股票价格 = 4) 的时候卖出,这笔交易所能获得利润 = 4-2 = 2。
  • 示例 2:
  • 输入:k = 2, prices = [3,2,6,5,0,3]
  • 输出:7 解释:在第 2 天 (股票价格 = 2) 的时候买入,在第 3 天 (股票价格 = 6) 的时候卖出, 这笔交易所能获得利润 = 6-2 = 4。随后,在第 5 天 (股票价格 = 0) 的时候买入,在第 6 天 (股票价格 = 3) 的时候卖出, 这笔交易所能获得利润 = 3-0 = 3 。

提示:

  • 0 <= k <= 100

  • 0 <= prices.length <= 1000

  • 0 <= prices[i] <= 1000

  • 动态规划

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

1——第一次持有股票

2——第一次不持有股票

3——第二次持有股票

4——第二次不持有股票

大家应该发现规律了吧 ,除了0以外,偶数就是卖出,奇数就是买入

题目要求是至多有K笔交易,那么j的范围就定义为 2 * k + 1 就可以了。

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

int[][] dp=new int[][]

2.确定递推公式

还要强调一下:dp[i][1]表示的是第i天,买入股票的状态,并不是说一定要第i天买入股票,这是很多同学容易陷入的误区

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

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

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

同理dp[i][2]也有两个操作:

  • 操作一:第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][1] + prices[i], dp[i - 1][2])

这里要类比j为奇数是买,偶数是卖的状态

3.初始化

第0天没有操作,这个最容易想到,就是0,即:dp[0][0] = 0;

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

第0天做第一次卖出,当天买入,当天卖出,所以dp[0][2] = 0;

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

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

可以推出dp[0][j]当j为奇数的时候都初始化为 -prices[0]

4.遍历顺序

前向后

5.打印dp数组

class Solution {
    public int maxProfit(int k, int[] prices) {
        int[][] dp=new int[prices.length+1][2*k+1];
        for(int j=1;j<2*k;j+=2){
            dp[0][j]=-prices[0];
        }
        for(int i=1;i<prices.length;i++){
            for(int j=0;j<2*k-1;j+=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[prices.length-1][2*k];

    }
}

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

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

相关文章

Linux系统用户密码过期_禁用过期策略

检查用户密码过期信息 使用Chage命令可以检查用户密码更改策略和过期信息。要检查特定用户的密码过期信息&#xff0c;可以使用以下命令&#xff1a; chage -l 用户禁用用户的密码过期 chage -m 0 -M 99999 -I -1 -E -1 用户这个命令将禁用该用户的密码过期。其中&#xff0…

企业性能测试成熟度

影响性能测试成熟度的5个内容项 1.性能测试流程规范 性能需求型模式-测试执行启动基本无规划&#xff0c;缺少标准流程规范&#xff0c;测试资产无法复用&#xff0c;测试结果无总结和沉淀性能常态化模式下流程规范->企业内部不同部门&#xff0c;各个团队共同制定并执行达…

Java“牵手”微店商品列表页数据采集+微店商品价格数据排序,微店API接口申请指南

微店平台创立于2011年5月&#xff0c;是北京口袋时尚科技开发的应用&#xff0c;2014年1月"微店"APP正式上线。微店已经从小微店主首选的开店工具转型为助力创业者发展兴趣、创立品牌、玩成事业的系统及基础设施。 微店商品列表数据包含商品名称、价格、销量、详情、…

Linux OpenGauss 数据库远程连接

目录 前言 1. Linux 安装 openGauss 2. Linux 安装cpolar 3. 创建openGauss主节点端口号公网地址 4. 远程连接openGauss 5. 固定连接TCP公网地址 6. 固定地址连接测试 前言 openGauss是一款开源关系型数据库管理系统&#xff0c;采用木兰宽松许可证v2发行。openGauss内…

centos7配置iscsi共享存储-tgtd

前言 iSCSI又称为IP-SAN&#xff0c;是一种基于因特网及SCSI-3协议下的存储技术&#xff0c;iSCSI利用了TCP/IP的port 860 和 3260 作为沟通的渠道。透过两部计算机之间利用iSCSI的协议来交换SCSI命令&#xff0c;让计算机可以透过高速的局域网集线来把SAN模拟成为本地的储存装…

MATLAB科学计算从入门到精通

&#x1f482; 个人网站:【工具大全】【游戏大全】【神级源码资源网】&#x1f91f; 前端学习课程&#xff1a;&#x1f449;【28个案例趣学前端】【400个JS面试题】&#x1f485; 寻找学习交流、摸鱼划水的小伙伴&#xff0c;请点击【摸鱼学习交流群】 MATLAB&#xff08;Matr…

软件测试/测试开发丨ChatGPT在测试计划中的应用策略

简介 测试计划是指描述了要进行的测试活动的范围、方法、资源和进度的文档。它主要包括测试项、被测特性、测试任务和风险控制等。 所以在使用ChatGPT输出结果之前&#xff0c;我们需要先将文档的内容框架梳理好&#xff0c;以及将内容范围划定好&#xff0c;必要的时候&…

2024年,企业知识库的趋势与前景

企业知识库是指企业内部存储和组织知识的集中化平台&#xff0c;包括文档、资料、经验、专业知识等。它的重要性在于提供了一个集中管理和共享知识的机制&#xff0c;对企业的发展和竞争力具有重大影响。 企业知识库的重要性 1. 提高工作效率和协作能力 企业知识库使得企业内…

国产触控笔哪个牌子好?适合开学季的电容笔推荐

学校的开学季节已经来临&#xff0c;伴随着科技的发展&#xff0c;新的电子产品和数码设备层出不穷。比如&#xff0c;智能手机&#xff0c;iPad平板&#xff0c;电容笔等等。但实际上&#xff0c;要想让iPad平板的性能&#xff0c;得到最大程度的提升&#xff0c;我觉得这个电…

【OpenCV • c++】图像噪音 | 椒盐噪音 | 高斯噪音

文章目录 一、什么是图像噪音二、椒盐噪声三、高斯噪声 一、什么是图像噪音 图像噪声是图像在获取或是传输过程中受到随机信号干扰&#xff0c;妨碍人们对图像理解及分析处理的信号。很多时候将图像噪声看做多维随机过程&#xff0c;因而描述噪声的方法完全可以借用随机过程的描…

C语言学习系列-->一篇带你看懂内存函数

文章目录 前言memcpy概述模拟实现 memmove概述模拟实现 memsetmemcmp总结 前言 上篇文章学习了C语言字符串函数&#xff0c;只是对字符串进行操作 本节&#xff0c;小编整理了一下C语言中的内存函数&#xff0c;对内存进行操作&#xff0c;只针对会内存块&#xff0c;不针对数据…

视频剪辑文案怎么写 视频剪辑文案用什么软件

视频剪辑文案与平面材料文案相比&#xff0c;在声音、画面的展现上自由度更高&#xff0c;视觉的丰满感也更高&#xff0c;是视听结合效果的呈现。本文会给大家介绍视频剪辑文案怎么写&#xff0c;视频剪辑文案用什么软件的相关内容&#xff0c;让大家可以在短时间内学会视频剪…

无涯教程-JavaScript - VDB函数

描述 VDB函数使用双倍余额递减法或您指定的某些其他方法返回您指定的任何期间(包括部分期间)的资产折旧。 VDB代表可变余额递减。 语法 VDB (cost, salvage, life, start_period, end_period, [factor], [no_switch])争论 Argument描述Required/OptionalCostThe initial co…

langchain主要模块(二):数据连接

langchain2之数据连接 langchain1.概念2.主要模块模型输入/输出 (Model I/O)数据连接 (Data connection)链式组装 (Chains)代理 (Agents)内存 (Memory)回调 (Callbacks) 3.数据连接1.数据加载&#xff1a;2.文档分割&#xff1a;3.文档向量化&#xff1a;4.存储和检索向量数据:…

单例模式-饿汉模式、懒汉模式

单例模式&#xff0c;是设计模式的一种。 在计算机这个圈子中&#xff0c;大佬们针对一些典型的场景&#xff0c;给出了一些典型的解决方案。 目录 单例模式 饿汉模式 懒汉模式 线程安全 单例模式 单例模式又可以理解为是单个实例&#xff08;对象&#xff09; 在有些场…

SG-Former实战:使用SG-Former实现图像分类任务(二)

文章目录 训练部分导入项目使用的库设置随机因子设置全局参数图像预处理与增强读取数据设置Loss设置模型设置优化器和学习率调整策略设置混合精度&#xff0c;DP多卡&#xff0c;EMA定义训练和验证函数训练函数验证函数调用训练和验证方法 运行以及结果查看测试完整的代码 在上…

Vue-video-player下载失败(npm i 报错)

Vue-video-player下载失败 最近在做项目时涉及到视频的播放组件&#xff0c;看了一下选择了Vue-video-player这个工具&#xff0c;实际在操作中是遇到许多问题的。 Q1:不支持谷歌 对于 “vue-video-player” 使用时出现 Adobe Flash 不再支持的提示&#xff0c;这是因为 Ado…

[maven] maven 简述及使用 maven 管理单个项目

maven 简述及使用 maven 管理单个项目 简单的说就是 maven 是一个项目管理工具&#xff0c;同时也是一个依赖管理工具。 使用 maven 生成的项目结构大致如下&#xff1a; project|- src/main/java|- src/main/resources|- src/test/java|- src/test/resources本篇笔记带一些…

服务器访问本机图片nginx配置

下面是Nginx的配置 然后是yml文件配置 后端返回给前端的数据直接返回这个地址就可以了 {"success": true,"code": "200","msg": "操作成功","data": [{"趋势": "https://120.26.98.185:8090/s…

Day62|图part1:深度优先搜索理论基础、797. 所有可能的路径

深度优先搜索&#xff08;DFS&#xff09;理论基础 图的实质和存储方式 图实际上就是一棵多叉树&#xff0c;可以用以下的数据结构进行表示&#xff1a; class Vertex {int id;vector<Vertex*> neighbors; };多叉树的&#xff1a; /* 基本的 N 叉树节点 */ class Tre…