算法训练营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;}
}
动规方法
- 确定dp数组(dp table)以及下标的含义
dp[i][0] 表示第i天持有股票所得最多现金 ,这里可能有同学疑惑,本题中只能买卖一次,持有股票之后哪还有现金呢?
其实一开始现金是0,那么加入第i天买入股票现金就是 -prices[i], 这是一个负数。
dp[i][1] 表示第i天不持有股票所得最多现金
注意这里说的是“持有”,“持有”不代表就是当天“买入”!也有可能是昨天就买入了,今天保持持有的状态
很多同学把“持有”和“买入”没区分清楚。
在下面递推公式分析中,我会进一步讲解。
- 确定递推公式
如果第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]);
这样递推公式我们就分析完了
- 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;
- 确定遍历顺序
从递推公式可以看出dp[i]都是由dp[i - 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. 买卖股票的最佳时机 题目链接🔥 给定一个数组 prices ,它的第 i 个元素 prices[i] 表示一支给定股票第 i 天的价格。 你只能选择 某一天 买入这只股票,并选择在 未来的某一个不同的日子 卖出该股票。设计一个算法来计算你所能获取的最大…...
Swagger 使用教程
Swagger 官网: API Documentation & Design Tools for Teams | Swagger 整合swagger 依赖: springfox-swagger2 springfox-swagger-ui <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-swagger2</a…...
单例模式-饿汉模式、懒汉模式
单例模式,是设计模式的一种。 在计算机这个圈子中,大佬们针对一些典型的场景,给出了一些典型的解决方案。 目录 单例模式 饿汉模式 懒汉模式 线程安全 单例模式 单例模式又可以理解为是单个实例(对象) 在有些场…...
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, …...
骨传导耳机对人体有危险吗?会损害听力吗?
如果在使用骨传导耳机的时候控制好时间和音量,是不会对人体带来危险和造成伤害的。 下面跟大家解释一下为什么骨传导耳机对人体没有危害,最大的原因就是骨传导耳机不需要空气传导,而是通过颅骨传到听觉中枢,传输过程中几乎没有噪…...
Spring Boot @Value读不到Nacos配置中心的值。(properties配置文件)
读不到配置中心的值, 配置中心的配置文件名字(Data ID的值)要以.properties结尾。 如果是yaml,就以yaml命名。...
Rocky Linux怎么安装mysql
Rocky Linux怎么安装mysql 在Rocky Linux上安装MySQL可以通过以下步骤实现: 更新软件包列表 ⭐️⭐️⭐️必要的,必须更新,更新会顺利很多!!!⭐️⭐️⭐️ 在安装MySQL之前,建议先更新软件包…...
轻量级软件FastGithub实现稳定访问github
当我们想访问全球最大的“同性交友网站”https://github.com/ 时,总会出现无法访问的界面,令人非常苦恼:幸运的是,有一种轻量级的软件可以帮助我们稳定地访问GitHub,那就是FastGithub。 什么是FastGithub?…...
芯科蓝牙BG27开发笔记6-精简第一个程序
1. 这些IO的控制代码在哪里? 还是蓝牙点灯程序: 首先需要对pinout做一些精简: 为了简化工程,去掉了不必要的IO。 至于PTI接口是什么,怎么用,不知道,现在不考虑: 但是提出以下问题…...
Android8.1 hal 加载wifi ko模块流程
Android如果发现wifi没有正常启动,从下面两个方面 1.是否正常编译出wifi ko文件,如果没有,说明编译的有问题,ko文件的地址vendor/lib/module/devices/wifi 2.如果有编译出ko文件,但还提示Wifi HAL start failed之类的…...
Unity SteamVR 开发教程:SteamVR Input 输入系统(2.x 以上版本)
文章目录 📕前言📕教程说明📕导入 SteamVR 插件📕SteamVR Input 窗口⭐action.json 文件⭐窗口面板⭐SteamVR_Input 目录 📕SteamVR 动作的类型⭐Boolean⭐Single⭐Vector2⭐Vector3⭐Pose⭐Skeleton⭐Vibration &…...
PyTorch中,卷积层、池化层、转置卷积层输出特征图形状计算公式总结
在PyTorch中,卷积层(Convolutional Layer)、池化层(Pooling Layer,例如最大池化层)、以及转置卷积层(Transpose Convolutional Layer,也称为反卷积层或上采样层)的输出特…...
Git Cherry Pick命令
1. 简介 Git是一款分布式版本控制系统,它提供了许多强大的功能来管理代码的版本和变更。其中之一就是cherry-pick命令,它允许我们选择某个分支上的一个或多个提交,并将它们应用到当前分支上。这个功能非常有用,可以帮助我们在不合…...
算法:经典贪心算法--跳一跳[2]
1、题目: 给定一个长度为 n 的 0 索引整数数组 nums。初始位置为 nums[0]。 每个元素 nums[i] 表示从索引 i 向前跳转的最大长度。换句话说,如果你在 nums[i] 处,你可以跳转到任意 nums[i j] 处: 返回到达 nums[n - 1] 的最小跳跃次数。生…...
Vue 和 React 前端框架的比较
一、什么是Vue? Vue[1] 是一个用于构建用户界面的渐进式、可逐步采用的 JavaScript 框架。它由 Evan You[2] 于 2014 年创建,并由一个活跃的开发者社区负责维护。 Vue 设计得非常轻量级、灵活和强大。它建立在一个基于组件的架构上,以组件为…...
【Java】什么是过滤器链(FilterChain )?哪些场景可以使用过滤器链?
文章目录 前言1、创建过滤器2、修改 web.xml3、运行项目并查看结果 前言 在一个 Web 应用程序中可以注册多个 Filter 程序,每个 Filter 程序都可以针对某一个 URL 进行拦截。如果多个 Filter 程序都对同一个 URL 进行拦截,那么这些 Filter 就会组成一个…...
Vue-video-player下载失败(npm i 报错)
Vue-video-player下载失败 最近在做项目时涉及到视频的播放组件,看了一下选择了Vue-video-player这个工具,实际在操作中是遇到许多问题的。 Q1:不支持谷歌 对于 “vue-video-player” 使用时出现 Adobe Flash 不再支持的提示,这是因为 Ado…...
数据在内存中的存储(1)
目录 1、整数在内存中的存储 原码、反码、补码: 2、大小端: 前提须知: 大小端存储方式: 字节的顺序: 概念: 判断机器是大端还是小端: 代码展示: 代码优化1.0: …...
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题 汽车制造涂装-总装缓存调序区调度优化问题 原题再现: 背景介绍 汽车制造厂主要由焊装车间、涂装车间、总装车间构成,每个车间有不同的生产偏好,如:焊装车间由于车身夹具的限制偏向最…...
文本直接生成3D游戏场景、功能,用ChatGPT方式开发游戏!
3D游戏开发平台Hiber3D通过谷歌的PaLM大语言模型,结合自身500多个模板库,以及数百万个成品3D场景进行微调,推出了一个全新游戏开发平台。 该平台在生成式AI加持下,用户可以像使用ChatGPT那样,通过文本问答方式快速创建…...
2023年会展行业研究报告
第一章 行业概况 1.1 定义 会展行业是一个多元化和复杂的领域,涵盖了许多不同的活动和功能。一般来说,会展业是指在一定的区域空间内,许多人聚集在一起形成的定期或者不定期,制度或者非制度,传递和交流信息的群众性的…...
【Redis】如何保证Redis缓存与数据库的一致性?
文章目录 1、四种同步策略2、更新缓存还是删除缓存2.1 更新缓存2.2 删除缓存 3、先操作数据库还是缓存3.1 先删除缓存再更新数据库3.2 先更新数据库再删除缓存 4、延时双删4.1 采用读写分离的架构怎么办? 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 中,对表单做在前置项未填写时禁用后置项交互并提示的效果。 情景 最近有这么个需求,某个业务中,要填写一张表单,其中有这样两项:选择数据连接和选择数据表,数据表是数据连接下所拥有的表。…...
Linux学习之MySQL建表
MySQL查询1 MySQL查询2 表管理 #1. 建库#1)库名命名规则仅可以使用数字、字母、下划线、不能纯数字,区分字母大小写,具有唯一性,不可使用MySQL命令或特殊字符#创建数据表时可以查看一下默认的字符集,8.0后创建数据库…...
Redis哨兵集群的介绍及搭建
Redis 是一款开源的、内存中的数据结构存储系统,它可以用作数据库、缓存和消息中间件。然而,作为一个单点服务,Redis 在面临硬件故障或者网络问题时可能会导致服务不可用。为了解决这个问题,Redis 提供了哨兵模式,一个…...
【zookeeper】zookeeper日常运维
本文将分享一些zookeeper在日常使用中一些维护经验。 zookeeper清理快照 脚本或者命令清理 zookeeper长时间运行,快照逐渐增多可能造成服务器磁盘被占满的情况,但我们不能贸然用rm命令删除快照文件,如果直接删完会导致丢失好多数据&#x…...
【工作记录】MQTT介绍、安装部署及springboot集成@20230912
背景 近期公司可能会有物联网设备相关项目内容,提前对用到的mqtt协议做预研和初步使用。 最初接触到mqtt协议应该是早些年的即时通讯吧,现在已经是物联网设备最热门的协议了。 作为记录,也希望能帮助到需要的朋友。 MQTT介绍 《MQTT 协议规…...
Flask 使用 JWT(一)
下面是一些 JWT 的使用场景: 1、 授权:这是 JWT 最常的使用场景。一旦用户登录,后续的每个请求都必须携带 JWT ,允许用户携带 Token 访问所有的路由、服务器和资源。单点登录时目前使用最广泛的一个场景,因为它开销小并且能够轻易的实现跨域访问。 2、信息交换:JWT Token…...
上海网站建设怎么弄/临沂seo代理商
8种机械键盘轴体对比本人程序员,要买一个写代码的键盘,请问红轴和茶轴怎么选?一、HMR介绍在我们开发react应用的时候,在配置了webpack-dev-server的前提下每一次的组件内容修改都需要手动的刷新浏览器,为了解决这个问题…...
nft制作网站/电商平台排行榜
这是因为中国的企业都没有长远的规划,或者说它们都不知道自己能生存多长时间,如此情况下谁会愿意冒险去尝试新的东西,即使是深圳科技企业其实同样不愿意尝试新的东西,你看它先后进入的手机、PC、服务器、云计算,哪个是它开拓出来的…...
网站做的比较好的公司吗/seo好学吗入门怎么学
修改tomcat/conf目录里面server.xml文件 例如下面这样新增一个8090端口,设置下appBase目录,这样就可以用一个tomcat监听多个端口,每个端口都可以放应用了。我这样新增下面这个配置以后,tomcat就监听了2个端口(8080&…...
易语言用电脑做网站服务器/互联网企业营销策略
最近更新: 2018-07-19注意:最新版iview已经提供多级表头功能 参考原理:利用多个Table组件通过显示和隐藏thead和tbody来拼接表格(较粗暴)htmljavascript非合并而来的列,请注意设置宽度(如下的宽度160)否则会被均分导致下面的行的列…...
1688网站建设与维护/百度推广客户端官方下载
做了某题之后发现trie的AC自动机太垃圾了,动不动就TLE,然后我就去学了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网站
导语提起病毒来,很多网友可能都会想到熊猫烧香,木马等等。它们的破坏力惊人,很多人因此也会谈“毒”色变。而程序员作为一群靠电脑吃饭的人,看过的病毒恐怕不比看过的片少,今天小编带大家盘点一下那些令程序员哭笑不得…...