当前位置: 首页 > news >正文

算法训练营day49|动态规划 part10:(LeetCode 121. 买卖股票的最佳时机、122.买卖股票的最佳时机II)

121. 买卖股票的最佳时机

题目链接🔥
给定一个数组 prices ,它的第 i 个元素 prices[i] 表示一支给定股票第 i 天的价格。
你只能选择 某一天 买入这只股票,并选择在 未来的某一个不同的日子 卖出该股票。设计一个算法来计算你所能获取的最大利润。
返回你可以从这笔交易中获取的最大利润。如果你不能获取任何利润,返回 0 。

示例 1:
输入:[7,1,5,3,6,4]
输出:5
解释:在第 2 天(股票价格 = 1)的时候买入,在第 5 天(股票价格 = 6)的时候卖出,最大利润 = 6-1 = 5 。注意利润不能是 7-1 = 6, 因为卖出价格需要大于买入价格;同时,你不能在买入前卖出股票。

示例 2:
输入:prices = [7,6,4,3,1]
输出:0
解释:在这种情况下, 没有交易完成, 所以最大利润为 0

贪心方法

取最左最小值,取最右最大值,那么得到的差值就是最大利润。

class Solution {
public:int maxProfit(vector<int>& prices) {int low = INT_MAX;int result = 0;for (int i = 0; i < prices.size(); i++) {low = min(low, prices[i]);  // 取最左最小价格result = max(result, prices[i] - low); // 直接取最大区间利润}return result;}
}

动规方法

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

dp[i][0] 表示第i天持有股票所得最多现金 ,这里可能有同学疑惑,本题中只能买卖一次,持有股票之后哪还有现金呢?

其实一开始现金是0,那么加入第i天买入股票现金就是 -prices[i], 这是一个负数。

dp[i][1] 表示第i天不持有股票所得最多现金

注意这里说的是“持有”,“持有”不代表就是当天“买入”!也有可能是昨天就买入了,今天保持持有的状态

很多同学把“持有”和“买入”没区分清楚。

在下面递推公式分析中,我会进一步讲解。

  1. 确定递推公式

如果第i天持有股票即dp[i][0], 那么可以由两个状态推出来

  • 第i-1天就持有股票,那么就保持现状,所得现金就是昨天持有股票的所得现金 即:dp[i - 1][0]
  • 第i天买入股票,所得现金就是买入今天的股票后所得现金即:-prices[i]

那么dp[i][0]应该选所得现金最大的,所以dp[i][0] = max(dp[i - 1][0], -prices[i]);

如果第i天不持有股票即dp[i][1], 也可以由两个状态推出来

  • 第i-1天就不持有股票,那么就保持现状,所得现金就是昨天不持有股票的所得现金 即:dp[i - 1][1]
  • 第i天卖出股票,所得现金就是按照今天股票价格卖出后所得现金即:prices[i] + dp[i - 1][0]

同样dp[i][1]取最大的,dp[i][1] = max(dp[i - 1][1], prices[i] + dp[i - 1][0]);

这样递推公式我们就分析完了

  1. dp数组如何初始化

由递推公式 dp[i][0] = max(dp[i - 1][0], -prices[i]); 和 dp[i][1] = max(dp[i - 1][1], prices[i] + dp[i - 1][0]);可以看出

其基础都是要从dp[0][0]和dp[0][1]推导出来。

那么dp[0][0]表示第0天持有股票,此时的持有股票就一定是买入股票了,因为不可能有前一天推出来,所以dp[0][0] -= prices[0];

dp[0][1]表示第0天不持有股票,不持有股票那么现金就是0,所以dp[0][1] = 0;

  1. 确定遍历顺序

从递推公式可以看出dp[i]都是由dp[i - 1]推导出来的,那么一定是从前向后遍历。

  1. 举例推导dp数组

在这里插入图片描述
dp[5][1]就是最终结果。

代码实现

class Solution {
public:int maxProfit(vector<int>& prices) {vector<vector<int>> dp(prices.size(),vector<int> (2));dp[0][0]=-prices[0];for(int i=1;i<prices.size();i++){dp[i][0]=max(-prices[i],dp[i-1][0]);dp[i][1]=max(dp[i-1][0]+prices[i],dp[i-1][1]);}return dp[prices.size()-1][1];}
};

122.买卖股票的最佳时机II

题目链接🔥🔥
给定一个数组,它的第 i 个元素是一支给定股票第 i 天的价格。
设计一个算法来计算你所能获取的最大利润。你可以尽可能地完成更多的交易(多次买卖一支股票)。
注意:你不能同时参与多笔交易(你必须在再次购买前出售掉之前的股票)。

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

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

示例 3:
输入: [7,6,4,3,1]
输出: 0
解释: 在这种情况下, 没有交易完成, 所以最大利润为 0。

提示:
1 <= prices.length <= 3 * 10 ^ 4
0 <= prices[i] <= 10 ^ 4

思路分析

本题和121. 买卖股票的最佳时机 的唯一区别是本题股票可以买卖多次了(注意只有一只股票,所以再次购买前要出售掉之前的股票)

在动规五部曲中,这个区别主要是体现在递推公式上,其他都和121. 买卖股票的最佳时机一样。

所以我们重点讲一讲递推公式。

这里重申一下dp数组的含义:

  • dp[i][0] 表示第i天持有股票所得现金。
  • dp[i][1] 表示第i天不持有股票所得最多现金

如果第i天持有股票即dp[i][0], 那么可以由两个状态推出来

  • 第i-1天就持有股票,那么就保持现状,所得现金就是昨天持有股票的所得现金 即:dp[i - 1][0]
  • 第i天买入股票,所得现金就是昨天不持有股票的所得现金减去 今天的股票价格 即:dp[i - 1][1] - prices[i]

注意这里和121. 买卖股票的最佳时机唯一不同的地方,就是推导dp[i][0]的时候,第i天买入股票的情况。

在121. 买卖股票的最佳时机中,因为股票全程只能买卖一次,所以如果买入股票,那么第i天持有股票即dp[i][0]一定就是 -prices[i]。

而本题,因为一只股票可以买卖多次,所以当第i天买入股票的时候,所持有的现金可能有之前买卖过的利润。

那么第i天持有股票即dp[i][0],如果是第i天买入股票,所得现金就是昨天不持有股票的所得现金 减去 今天的股票价格 即:dp[i - 1][1] - prices[i]。

再来看看如果第i天不持有股票即dp[i][1]的情况, 依然可以由两个状态推出来

第i-1天就不持有股票,那么就保持现状,所得现金就是昨天不持有股票的所得现金 即:dp[i - 1][1]
第i天卖出股票,所得现金就是按照今天股票价格卖出后所得现金即:prices[i] + dp[i - 1][0]
注意这里和121. 买卖股票的最佳时机就是一样的逻辑,卖出股票收获利润(可能是负值)天经地义!

代码如下:(注意代码中的注释,标记了和121.买卖股票的最佳时机唯一不同的地方)

代码实现

class Solution {
public:int maxProfit(vector<int>& prices) {vector<vector<int>> dp(prices.size(),vector<int> (2));dp[0][0]=-prices[0];for (int i = 1; i < prices.size(); i++) {dp[i][0] = max(dp[i - 1][0], dp[i - 1][1] - prices[i]); // 注意这里是和121. 买卖股票的最佳时机唯一不同的地方。dp[i][1] = max(dp[i - 1][1], dp[i - 1][0] + prices[i]);}return dp[prices.size()-1][1];}
};

思考总结

买入股票的时候,可能会有之前买卖的利润即:dp[i - 1][1],所以dp[i - 1][1] - prices[i]。

相关文章:

算法训练营day49|动态规划 part10:(LeetCode 121. 买卖股票的最佳时机、122.买卖股票的最佳时机II)

121. 买卖股票的最佳时机 题目链接&#x1f525; 给定一个数组 prices &#xff0c;它的第 i 个元素 prices[i] 表示一支给定股票第 i 天的价格。 你只能选择 某一天 买入这只股票&#xff0c;并选择在 未来的某一个不同的日子 卖出该股票。设计一个算法来计算你所能获取的最大…...

Swagger 使用教程

Swagger 官网&#xff1a; API Documentation & Design Tools for Teams | Swagger 整合swagger 依赖&#xff1a; springfox-swagger2 springfox-swagger-ui <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-swagger2</a…...

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

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

UG\NX二次开发 复制3元素的double数组到另一个数组 UF_VEC3_copy

文章作者:里海 来源网站:王牌飞行员_里海_里海NX二次开发3000例,里海BlockUI专栏,C\C++-CSDN博客 简介: UG\NX二次开发 复制3元素的double数组到另一个数组 UF_VEC3_copy。仔细看第二段代码 。 效果: 代码: #include "me.hpp"void ufusr(char* param, …...

骨传导耳机对人体有危险吗?会损害听力吗?

如果在使用骨传导耳机的时候控制好时间和音量&#xff0c;是不会对人体带来危险和造成伤害的。 下面跟大家解释一下为什么骨传导耳机对人体没有危害&#xff0c;最大的原因就是骨传导耳机不需要空气传导&#xff0c;而是通过颅骨传到听觉中枢&#xff0c;传输过程中几乎没有噪…...

Spring Boot @Value读不到Nacos配置中心的值。(properties配置文件)

读不到配置中心的值&#xff0c; 配置中心的配置文件名字&#xff08;Data ID的值&#xff09;要以.properties结尾。 如果是yaml&#xff0c;就以yaml命名。...

Rocky Linux怎么安装mysql

Rocky Linux怎么安装mysql 在Rocky Linux上安装MySQL可以通过以下步骤实现&#xff1a; 更新软件包列表 ⭐️⭐️⭐️必要的&#xff0c;必须更新&#xff0c;更新会顺利很多&#xff01;&#xff01;&#xff01;⭐️⭐️⭐️ 在安装MySQL之前&#xff0c;建议先更新软件包…...

轻量级软件FastGithub实现稳定访问github

当我们想访问全球最大的“同性交友网站”https://github.com/ 时&#xff0c;总会出现无法访问的界面&#xff0c;令人非常苦恼&#xff1a;幸运的是&#xff0c;有一种轻量级的软件可以帮助我们稳定地访问GitHub&#xff0c;那就是FastGithub。 什么是FastGithub&#xff1f…...

芯科蓝牙BG27开发笔记6-精简第一个程序

1. 这些IO的控制代码在哪里&#xff1f; 还是蓝牙点灯程序&#xff1a; 首先需要对pinout做一些精简&#xff1a; 为了简化工程&#xff0c;去掉了不必要的IO。 至于PTI接口是什么&#xff0c;怎么用&#xff0c;不知道&#xff0c;现在不考虑&#xff1a; 但是提出以下问题…...

Android8.1 hal 加载wifi ko模块流程

Android如果发现wifi没有正常启动&#xff0c;从下面两个方面 1.是否正常编译出wifi ko文件&#xff0c;如果没有&#xff0c;说明编译的有问题&#xff0c;ko文件的地址vendor/lib/module/devices/wifi 2.如果有编译出ko文件&#xff0c;但还提示Wifi HAL start failed之类的…...

Unity SteamVR 开发教程:SteamVR Input 输入系统(2.x 以上版本)

文章目录 &#x1f4d5;前言&#x1f4d5;教程说明&#x1f4d5;导入 SteamVR 插件&#x1f4d5;SteamVR Input 窗口⭐action.json 文件⭐窗口面板⭐SteamVR_Input 目录 &#x1f4d5;SteamVR 动作的类型⭐Boolean⭐Single⭐Vector2⭐Vector3⭐Pose⭐Skeleton⭐Vibration &…...

PyTorch中,卷积层、池化层、转置卷积层输出特征图形状计算公式总结

在PyTorch中&#xff0c;卷积层&#xff08;Convolutional Layer&#xff09;、池化层&#xff08;Pooling Layer&#xff0c;例如最大池化层&#xff09;、以及转置卷积层&#xff08;Transpose Convolutional Layer&#xff0c;也称为反卷积层或上采样层&#xff09;的输出特…...

Git Cherry Pick命令

1. 简介 Git是一款分布式版本控制系统&#xff0c;它提供了许多强大的功能来管理代码的版本和变更。其中之一就是cherry-pick命令&#xff0c;它允许我们选择某个分支上的一个或多个提交&#xff0c;并将它们应用到当前分支上。这个功能非常有用&#xff0c;可以帮助我们在不合…...

算法:经典贪心算法--跳一跳[2]

1、题目&#xff1a; 给定一个长度为 n 的 0 索引整数数组 nums。初始位置为 nums[0]。 每个元素 nums[i] 表示从索引 i 向前跳转的最大长度。换句话说&#xff0c;如果你在 nums[i] 处&#xff0c;你可以跳转到任意 nums[i j] 处: 返回到达 nums[n - 1] 的最小跳跃次数。生…...

Vue 和 React 前端框架的比较

一、什么是Vue&#xff1f; Vue[1] 是一个用于构建用户界面的渐进式、可逐步采用的 JavaScript 框架。它由 Evan You[2] 于 2014 年创建&#xff0c;并由一个活跃的开发者社区负责维护。 Vue 设计得非常轻量级、灵活和强大。它建立在一个基于组件的架构上&#xff0c;以组件为…...

【Java】什么是过滤器链(FilterChain )?哪些场景可以使用过滤器链?

文章目录 前言1、创建过滤器2、修改 web.xml3、运行项目并查看结果 前言 在一个 Web 应用程序中可以注册多个 Filter 程序&#xff0c;每个 Filter 程序都可以针对某一个 URL 进行拦截。如果多个 Filter 程序都对同一个 URL 进行拦截&#xff0c;那么这些 Filter 就会组成一个…...

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

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

数据在内存中的存储(1)

目录 1、整数在内存中的存储 原码、反码、补码&#xff1a; 2、大小端&#xff1a; 前提须知&#xff1a; 大小端存储方式&#xff1a; 字节的顺序&#xff1a; 概念&#xff1a; 判断机器是大端还是小端&#xff1a; 代码展示&#xff1a; 代码优化1.0&#xff1a; …...

LINUX常用命令练习

显示LINUX系统当前的日期和时间。 date以 yyyy/mm/dd的格式显示系统当前的日期 date %Y/%m/%d以 yyyy-mm-dd的格式显示系统当前的日期 date %Y-%m-%d查看在线用户信息 who显示当前月份的日历 cal显示2023年整年的日历 cal 2023显示2023年9月的日历 cal 9 2023查看LINUX系统的Sh…...

2022年全国研究生数学建模竞赛华为杯C题汽车制造涂装-总装缓存调序区调度优化问题求解全过程文档及程序

2022年全国研究生数学建模竞赛华为杯 C题 汽车制造涂装-总装缓存调序区调度优化问题 原题再现&#xff1a; 背景介绍   汽车制造厂主要由焊装车间、涂装车间、总装车间构成&#xff0c;每个车间有不同的生产偏好&#xff0c;如&#xff1a;焊装车间由于车身夹具的限制偏向最…...

文本直接生成3D游戏场景、功能,用ChatGPT方式开发游戏!

3D游戏开发平台Hiber3D通过谷歌的PaLM大语言模型&#xff0c;结合自身500多个模板库&#xff0c;以及数百万个成品3D场景进行微调&#xff0c;推出了一个全新游戏开发平台。 该平台在生成式AI加持下&#xff0c;用户可以像使用ChatGPT那样&#xff0c;通过文本问答方式快速创建…...

2023年会展行业研究报告

第一章 行业概况 1.1 定义 会展行业是一个多元化和复杂的领域&#xff0c;涵盖了许多不同的活动和功能。一般来说&#xff0c;会展业是指在一定的区域空间内&#xff0c;许多人聚集在一起形成的定期或者不定期&#xff0c;制度或者非制度&#xff0c;传递和交流信息的群众性的…...

【Redis】如何保证Redis缓存与数据库的一致性?

文章目录 1、四种同步策略2、更新缓存还是删除缓存2.1 更新缓存2.2 删除缓存 3、先操作数据库还是缓存3.1 先删除缓存再更新数据库3.2 先更新数据库再删除缓存 4、延时双删4.1 采用读写分离的架构怎么办&#xff1f; 5、利用消息队列进行删除的补偿 1、四种同步策略 想要保证缓…...

MATLAB中ischange函数用法

目录 语法 说明 示例 均值的变化 线性区的变化 矩阵数据 ischange函数的功能是查找数据中的突然变化。 语法 TF ischange(A) TF ischange(A,method) TF ischange(___,dim) TF ischange(___,Name,Value) [TF,S1] ischange(___) [TF,S1,S2] ischange(___) 说明 ​…...

【React + Ant Design】表单如何在前置项未填写时禁止后置项交互并提示

在 react antd 中&#xff0c;对表单做在前置项未填写时禁用后置项交互并提示的效果。 情景 最近有这么个需求&#xff0c;某个业务中&#xff0c;要填写一张表单&#xff0c;其中有这样两项&#xff1a;选择数据连接和选择数据表&#xff0c;数据表是数据连接下所拥有的表。…...

Linux学习之MySQL建表

MySQL查询1 MySQL查询2 表管理 #1. 建库#1&#xff09;库名命名规则仅可以使用数字、字母、下划线、不能纯数字&#xff0c;区分字母大小写&#xff0c;具有唯一性&#xff0c;不可使用MySQL命令或特殊字符#创建数据表时可以查看一下默认的字符集&#xff0c;8.0后创建数据库…...

Redis哨兵集群的介绍及搭建

Redis 是一款开源的、内存中的数据结构存储系统&#xff0c;它可以用作数据库、缓存和消息中间件。然而&#xff0c;作为一个单点服务&#xff0c;Redis 在面临硬件故障或者网络问题时可能会导致服务不可用。为了解决这个问题&#xff0c;Redis 提供了哨兵模式&#xff0c;一个…...

【zookeeper】zookeeper日常运维

本文将分享一些zookeeper在日常使用中一些维护经验。 zookeeper清理快照 脚本或者命令清理 zookeeper长时间运行&#xff0c;快照逐渐增多可能造成服务器磁盘被占满的情况&#xff0c;但我们不能贸然用rm命令删除快照文件&#xff0c;如果直接删完会导致丢失好多数据&#x…...

【工作记录】MQTT介绍、安装部署及springboot集成@20230912

背景 近期公司可能会有物联网设备相关项目内容&#xff0c;提前对用到的mqtt协议做预研和初步使用。 最初接触到mqtt协议应该是早些年的即时通讯吧&#xff0c;现在已经是物联网设备最热门的协议了。 作为记录&#xff0c;也希望能帮助到需要的朋友。 MQTT介绍 《MQTT 协议规…...

Flask 使用 JWT(一)

下面是一些 JWT 的使用场景: 1、 授权:这是 JWT 最常的使用场景。一旦用户登录,后续的每个请求都必须携带 JWT ,允许用户携带 Token 访问所有的路由、服务器和资源。单点登录时目前使用最广泛的一个场景,因为它开销小并且能够轻易的实现跨域访问。 2、信息交换:JWT Token…...

上海网站建设怎么弄/临沂seo代理商

8种机械键盘轴体对比本人程序员&#xff0c;要买一个写代码的键盘&#xff0c;请问红轴和茶轴怎么选&#xff1f;一、HMR介绍在我们开发react应用的时候&#xff0c;在配置了webpack-dev-server的前提下每一次的组件内容修改都需要手动的刷新浏览器&#xff0c;为了解决这个问题…...

nft制作网站/电商平台排行榜

这是因为中国的企业都没有长远的规划&#xff0c;或者说它们都不知道自己能生存多长时间,如此情况下谁会愿意冒险去尝试新的东西&#xff0c;即使是深圳科技企业其实同样不愿意尝试新的东西&#xff0c;你看它先后进入的手机、PC、服务器、云计算&#xff0c;哪个是它开拓出来的…...

网站做的比较好的公司吗/seo好学吗入门怎么学

修改tomcat/conf目录里面server.xml文件 例如下面这样新增一个8090端口&#xff0c;设置下appBase目录&#xff0c;这样就可以用一个tomcat监听多个端口&#xff0c;每个端口都可以放应用了。我这样新增下面这个配置以后&#xff0c;tomcat就监听了2个端口&#xff08;8080&…...

易语言用电脑做网站服务器/互联网企业营销策略

最近更新&#xff1a; 2018-07-19注意&#xff1a;最新版iview已经提供多级表头功能 参考原理&#xff1a;利用多个Table组件通过显示和隐藏thead和tbody来拼接表格(较粗暴)htmljavascript非合并而来的列&#xff0c;请注意设置宽度(如下的宽度160)否则会被均分导致下面的行的列…...

1688网站建设与维护/百度推广客户端官方下载

做了某题之后发现trie的AC自动机太垃圾了&#xff0c;动不动就TLE&#xff0c;然后我就去学了trie图。 #include<iostream> #include<cstdio> using namespace std; struct trie {int count;trie *fail,*nxt[26];trie(){count0;failNULL;for(int i0;i<26;i)nxt[…...

国家企业信用信息官网/完善的seo网站

导语提起病毒来&#xff0c;很多网友可能都会想到熊猫烧香&#xff0c;木马等等。它们的破坏力惊人&#xff0c;很多人因此也会谈“毒”色变。而程序员作为一群靠电脑吃饭的人&#xff0c;看过的病毒恐怕不比看过的片少&#xff0c;今天小编带大家盘点一下那些令程序员哭笑不得…...