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

代码随想录打卡Day41

最近事情好多。。全堆一块了,今天先写两题吧,剩下一题明天解决。

121. 买卖股票的最佳时机

这道题纯不会,不知道该怎么构造dp数组,更不知道dp数组的含义,看完讲解以后感觉这样的dp数组构造还挺巧妙的,第一次见这样构造dp数组的。这道题的循环中需要同时维护两个状态,一种是第i天保持持有股票状态时的最大收益(不一定是在第i天买入,有可能在之前就买入了),一种是第i天保持未持有股票状态时的最大收益(不一定是在第i天卖出,也有可能是在之前就已经卖出了),这样定义两个状态就把所有状态都包含了,由于这道题只能买卖一次股票,所以状态转移很简单:
1.当第i天持有股票时
如果在第i天之前就已经买入股票了,那么第i天仍然持有股票,则获得的收益已经被定死,就与前一天持有股票的收益是相同的,因为持有股票而不卖出的话,收益一直都是负数(购买股票需要花钱,收益就是买入当天股票价格的负数);如果是第i天当天买入的股票,则当天的收益为-prices[i](买股票的成本)。将两种情况作比较取较大值,只要当天的价格相比于之前的价格高,那么当天买入的收益一定不是最大的,收益最大化的必要条件之一是购入股票的成本尽可能低。
2.当第i天未持有股票时
如果第i天之前就已经卖出股票,那么后序也就不能再买卖股票,属于是买定离手,不能反悔了,后面的收益也就不再变动,和前一天未持有股票的收益相同;如果是第i天才把股票卖出,则前一天必然是持有股票的状态,直接将前一天持有股票的最大收益(此前购买股票的最低成本)与当天股票价格相加即可,收益最大化的另一必要条件之一是卖出股票的价格尽可能高。
了解了dp数组的具体含义,初始化也很好办了。

class Solution {
public:int maxProfit(vector<int>& prices) {//1.确定dp[i][0]的含义:第i天保持持有股票情况下,所能获得的最大收益为dp[i][0]//      dp[i][1]的含义:第i天未持有股票的情况下,所能获得的最大收益为dp[i][1]//2.确定递推公式dp[i][0] = max(dp[i - 1][0], -prices[i]);//             dp[i][1] = max(dp[i - 1][1], dp[i - 1][0] + prices[i])//3.dp数组初始化 dp[0][0] = -prices[0], dp[0][1] = 0;//4.确定遍历顺序:从小到大遍历//5.打印数组(省略)int m = prices.size();vector<vector<int>> dp(m, vector<int> (2));//初始化dp[0][0] = -prices[0];dp[0][1] = 0;for(int i = 1; i < m; i++){dp[i][0] = max(dp[i - 1][0], -prices[i]);dp[i][1] = max(dp[i - 1][1], dp[i - 1][0] + prices[i]);}return dp[m - 1][1];}
};

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

这道题比上一道题略难一点,但是思路大同小异,这道题与上一道题的区别在于这道题可以买卖多次股票。在代码实现中区别体现在哪里呢?主要是体现在递推公式上。
1.当第i天持有股票时
若是在第i天之前买入了股票,则在上一次买入股票之前可能还涉及多次股票买卖操作,因此在最近一次买入股票后,收益未必是负数(此前可能通过多次买卖股票实现了盈利),至少在第i - 1天依然是持有股票的状态,所以这种情况下的最大收益为dp[i - 1][0];若在第i天买入了股票,则第i - 1天必然是未持有股票的状态,因此这种情况下的最大收益是dp[i - 1][1] - prices[i];两者取较大值即可。
2.当第i天未持有股票时
若在第i天之前就已经是未持有状态(可能从未买过,也可能已经卖出),则至少在i - 1天也处于未持有状态,则这种情况下第i天的最大收益应当与第i - 1天的最大收益持平;若在第i天才卖出股票,则第i - 1天必然是持有股票的状态,则用第i - 1持有股票的最大收益加上第i天的股票价格即可。
除了递推公式上有细微差别外,其余地方完全相同。

class Solution {
public:int maxProfit(vector<int>& prices) {//1.确定dp[i][0]的含义:第i天保持持有股票情况下,所能获得的最大收益为dp[i][0]//      dp[i][1]的含义:第i天未持有股票的情况下,所能获得的最大收益为dp[i][1]//2.确定递推公式dp[i][0] = max(dp[i - 1][0], dp[i - 1][1] - prices[i]);//             dp[i][1] = max(dp[i - 1][1], dp[i - 1][0] + prices[i])//3.dp数组初始化 dp[0][0] = -price[0], dp[0][1] = 0;//4.确定遍历顺序:从小到大遍历//5.打印数组(省略)int m = prices.size();vector<vector<int>> dp(m, vector<int> (2));//初始化dp[0][0] = -prices[0];dp[0][1] = 0;for(int i = 1; i < m; i++){dp[i][0] = max(dp[i - 1][0], dp[i - 1][1] - prices[i]);dp[i][1] = max(dp[i - 1][1], dp[i - 1][0] + prices[i]);}return dp[m - 1][1];}
};

实在是太累了,明天再说。


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

这道题是困难题,第一道题是必须买卖一次,第二道题是没有买卖次数限制,这道题是最多可以买卖两次,也可以不做任何买卖。这道题的难点主要还是在于dp数组的构造。主要有以下5种状态:
1.第i天为从未进行过任何买卖操作的状态
在第i天及以前,从未进行过任何股票的买卖操作,此时取得的最大收益必然为0。
2.第i天为第一次持有股票的状态
若在第i天之前已经买入了股票,至少在i - 1天也是持有状态,则第i天的最大收益为dp[i - 1][1](股票尚未卖出);若在第i天买入股票,则第i天的最大收益为dp[i - 1][0] - prices[i]。二者需要取最大值。
3.第i天为第一次未持有股票的状态
若在第i天之前已经卖出了股票,至少在第i - 1天也是未持有状态,则第i天的最大收益为dp[i - 1][2] (第二次股票尚未买入);若在第i天卖出股票,则第i天的最大收益为dp[i - 1][1] + prices[i]。二者需要取最大值。
4.第i天为第二次持有股票的状态
若在第i天之前已经买入了第二次股票,至少在第i - 1天也是持有状态,则第i天的最大收益为dp[i - 1][3](股票尚未卖出);若在第i天当天买入了第二次股票,则第i天的最大收益为dp[i - 1][2] - prices[i]。二者需要取最大值。
5.第i天为第二次未持有股票的状态
若在第i天之前已经卖出了第二次股票,至少在第i - 1天也是未持有状态,则第i天的收益为dp[i - 1][4](股票已经卖出);若在第i天当天卖出股票,则第i天的最大收益为dp[i - 1][3] + prices[i]。
注意,股票允许当天买入当天卖出,所以直接返回最后一天未持有股票的最大收益即可(如果只需要买卖一次就能得到最大收益,在此基础上选择某一天当天买卖第二次股票即可)。
初始化和遍历顺序没什么难的,这里就不写了。

class Solution {
public:int maxProfit(vector<int>& prices) {//1.确定dp[i][0]的含义:第i天仍然没有进行过任何买卖操作的情况下,所能获得的最大收益为dp[i][0]//      dp[i][1]的含义:第i天为第一次持有股票的情况下,所能获得的最大收益为dp[i][1]//      dp[i][2]的含义:第i天为第一次未持有股票的情况下,所能获得的最大收益为dp[i][2]//      dp[i][3]的含义:第i天为第二次持有股票的情况下,所能获得的最大收益为dp[i][3]//      dp[i][4]的含义:第i天为第二次未持有股票的情况下,所能获得的最大收益为dp[i][4]//2.确定递推公式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])//3.dp数组初始化 dp[0][0] = 0;//              dp[0][1] = -prices[0];//              dp[0][2] = 0;//              dp[0][3] = -prices[0];//              dp[0][4] = 0;//4.确定遍历顺序:从小到大遍历//5.打印数组(省略)int m = prices.size();vector<vector<int>> dp(m, vector<int> (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 < m; 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[m - 1][4];}
};

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 研一奖学金计划2024/9/23有感
  • 【ARM】armv8的虚拟化深度解读
  • 神经网络激活函数
  • API代理是什么?解读其原理与作用
  • 累加求和-C语言
  • [大语言模型-论文精读] Diffusion Model技术-通过时间和空间组合扩散模型生成复杂的3D人物动作
  • 大模型prompt先关
  • 【网络安全】密码学的新进展
  • 大模型之基准测试集(Benchmark)-给通义千问2.0做测评的10个权威测基准测评集
  • windows使用JEnv实现一键临时或全局切换java版本
  • WebGL动画与交互
  • Maya学习笔记:物体的层级关系
  • 若依生成主子表
  • Vue3:v-model实现组件通信
  • numpy.rollcirculant
  • co.js - 让异步代码同步化
  • css布局,左右固定中间自适应实现
  • Elasticsearch 参考指南(升级前重新索引)
  • ERLANG 网工修炼笔记 ---- UDP
  • Java程序员幽默爆笑锦集
  • mysql innodb 索引使用指南
  • nodejs调试方法
  • PAT A1050
  • PHP 的 SAPI 是个什么东西
  • Redis的resp协议
  • Swift 中的尾递归和蹦床
  • Synchronized 关键字使用、底层原理、JDK1.6 之后的底层优化以及 和ReenTrantLock 的对比...
  • vue 个人积累(使用工具,组件)
  • webpack项目中使用grunt监听文件变动自动打包编译
  • Yeoman_Bower_Grunt
  • 从@property说起(二)当我们写下@property (nonatomic, weak) id obj时,我们究竟写了什么...
  • 关于 Linux 进程的 UID、EUID、GID 和 EGID
  • 悄悄地说一个bug
  • 如何用vue打造一个移动端音乐播放器
  • 深入体验bash on windows,在windows上搭建原生的linux开发环境,酷!
  • 微服务核心架构梳理
  • 验证码识别技术——15分钟带你突破各种复杂不定长验证码
  • 3月27日云栖精选夜读 | 从 “城市大脑”实践,瞭望未来城市源起 ...
  • FaaS 的简单实践
  • PostgreSQL之连接数修改
  • 曾刷新两项世界纪录,腾讯优图人脸检测算法 DSFD 正式开源 ...
  • #HarmonyOS:软件安装window和mac预览Hello World
  • #QT(一种朴素的计算器实现方法)
  • #Ubuntu(修改root信息)
  • #我与Java虚拟机的故事#连载15:完整阅读的第一本技术书籍
  • (windows2012共享文件夹和防火墙设置
  • (附源码)spring boot北京冬奥会志愿者报名系统 毕业设计 150947
  • (附源码)springboot金融新闻信息服务系统 毕业设计651450
  • (附源码)ssm高校志愿者服务系统 毕业设计 011648
  • (附源码)计算机毕业设计ssm高校《大学语文》课程作业在线管理系统
  • (剑指Offer)面试题41:和为s的连续正数序列
  • (转)拼包函数及网络封包的异常处理(含代码)
  • .net core 微服务_.NET Core 3.0中用 Code-First 方式创建 gRPC 服务与客户端
  • .NET Framework 3.5中序列化成JSON数据及JSON数据的反序列化,以及jQuery的调用JSON
  • .NET Framework 和 .NET Core 在默认情况下垃圾回收(GC)机制的不同(局部变量部分)