代码随想录算法训练营第四十九天|121. 买卖股票的最佳时机、122.买卖股票的最佳时机II

代码随想录算法训练营第四十九天|121. 买卖股票的最佳时机、122.买卖股票的最佳时机II

买卖股票的最佳时机

121. 买卖股票的最佳时机
文章讲解:https://programmercarl.com/0121.%E4%B9%B0%E5%8D%96%E8%82%A1%E7%A5%A8%E7%9A%84%E6%9C%80%E4%BD%B3%E6%97%B6%E6%9C%BA.html
题目链接:https://leetcode.cn/problems/best-time-to-buy-and-sell-stock/
视频讲解:https://www.bilibili.com/video/BV1Xe4y1u77q/

自己看到题目的第一想法

看完代码随想录之后的想法

dp数组定义:

  • dp[i][0]:第i天,持有股票最大现金。
  • dp[i][1]:第i天,不持有股票的最大现金。
  • 最大值:Math.max(dp[length - 1][0],dp[length - 1][1])
  • 注意,这里是“持有”,不是第i天就买第i天的股票,可能i-1天就买了然后第i天只是持有这个i-1天买的股票。同理“不持有”,也不是指第i天卖了股票,而是第i天不持有,可能第i-1天卖的,可能也是第i天卖的。
  • 个人理解,一直用持有去算最大。同理,一直用不持有去算最大。

递推公式:

  • dp[i][0]第i天,持有股票最大现金的计算方式:可能第i-1天就买入了,因此可能价值为dp[i-1][0]。也可能是第i天买入的,第i天买入的话最大现金就-prices[i],又因为本题买卖就只有一次,因此dp[i][0]的递推公式即为 Math.max(dp[i-1][0],-prices[i]);
  • dp[i][1]第i天,不持有股票的最大现金的计算方式:可能第i-1天就不持有了,因此dp[i][1]可能的价值为dp[i-1][1];

确定初始化值:

  • 这里主要是初始化dp[0][0]和dp[0][1],dp[0][0]表示持有最大现金,第0天未买入的最大价值则为dp[0][0]=0;第0天买入的最大价值dp[0][1] = -prices[0];

如果第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]);

自己实现过程中遇到哪些困难

自己第一次实现的错误,在实现过程中,把递推公式,理解成第i天买入。而代码随想录的概念是第i天持有股票,或者不持有股票,这里指的是有没有股票,而不是第i天做买入、卖出的动作。
自己实现时的问题代码:

public int maxProfit(int[] prices) {// 动态规划五步曲// 1. 确定dp数组定义,dp[i][0]和dp[i][1],dp[i][0]表示第i天时,不持有第i天股票的最大价值。dp[i][1]表示第i天,持有第i天股票的最大价值int[][] dp = new int[prices.length][prices.length];// 2. 确定递推公式 // 2.1 第i天时不持有第i天股票的价值和前一天的价值一样 dp[i][0] = dp[i-1][0];// 2.2 第i天持有第i天股票的价值为 dp[i][1] = -prices[i]。因为这里只能买卖一次// 3. 确定初始值dp[0][0] = 0;dp[0][1] = 0 - prices[0];// 4. 确定遍历顺序,因为值是从i-1推到i的,因此从小到大遍历。for(int i = 1; i < prices.length; i++){dp[i][0] = dp[i-1][0];dp[i][1] = 0 - prices[i];}return Math.max(dp[prices.length - 1][0],dp[prices.length - 1][1]);}

修改后的代码:

public int maxProfit(int[] prices) {// 动态规划五步曲// 1. 确定dp数组定义,dp[i][0]和dp[i][1],dp[i][0]表示第i天时,不持有第i天股票的最大价值。dp[i][1]表示第i天,持有第i天股票的最大价值int[][] dp = new int[prices.length][prices.length];// 2. 确定递推公式 // 第i天持有股票即dp[i][0],可能之前就持有了,可能是第i天买入:Math.max(dp[i - 1][0], -prices[i]);// 第i天不持有股票即dp[i][1],可能是之前就不持有了,可能是第i天卖掉:Math.max(dp[i - 1][1], prices[i] + dp[i - 1][0]);// 3. 确定初始值dp[0][0] -= prices[0];dp[0][1] = 0;// 4. 确定遍历顺序,因为值是从i-1推到i的,因此从小到大遍历。for(int i = 1; i < prices.length; i++){// 第i天持有股票即dp[i][0],可能之前就持有了,可能是第i天买入dp[i][0] = Math.max(dp[i - 1][0], -prices[i]);// 第i天不持有股票即dp[i][1],可能是之前就不持有了,可能是第i天卖掉dp[i][1] = Math.max(dp[i - 1][1], prices[i] + dp[i - 1][0]);}return dp[prices.length - 1][1];
}

买卖股票的最佳时机II

122.买卖股票的最佳时机II
文章讲解:https://programmercarl.com/0122.%E4%B9%B0%E5%8D%96%E8%82%A1%E7%A5%A8%E7%9A%84%E6%9C%80%E4%BD%B3%E6%97%B6%E6%9C%BAII%EF%BC%88%E5%8A%A8%E6%80%81%E8%A7%84%E5%88%92%EF%BC%89.html
题目链接:https://leetcode.cn/problems/best-time-to-buy-and-sell-stock-ii/
视频讲解:https://www.bilibili.com/video/BV1D24y1Q7Ls/

自己看到题目的第一想法

和121. 买卖股票的最佳时机的题目类似,但是该题目有了多次的买与卖,121题只有一次买卖。最大的区别就是买入和卖出最大值都需要关心上一天的值。

看完代码随想录之后的想法

买入和卖出最大值都需要关心上一天的值。

自己实现过程中遇到哪些困难

自己实现这里递推公式处理错了,自己实现的错误代码:

public int maxProfit(int[] prices) {if(prices.length == 1){return 0;}// 动态规划五步骤// 1. 确定dp定义 dp[i][0]:第i天,未持有股票的最大价值;dp[i][1],第i天,持有股票的最大价值int[][] dp = new int[prices.length][prices.length];// 2. 确定推导公式 // 2.1 第i天,未持有股票,可能之前就一直不持有dp[i][0] = dp[i - 1][0] ,也可能第i天卖了,dp[i][0] = dp[i - 1][0] + prices[i]// 2.2 第i天,持有股票,可能之前就一直持有dp[i][1] = dp[i-1][1],也可能第i天买入,dp[i - 1][1] - prices[i]// 3. 确定初始化值dp[0][0] = 0;dp[0][1] -= prices[0];// 4. 确定遍历顺序(这里错误)for(int i = 1; i < prices.length; i++){dp[i][0] = Math.max(dp[i-1][0],dp[i-1][0] + prices[i]);dp[i][1] = Math.max(dp[i-1][1],dp[i-1][1] - prices[i]);}return dp[prices.length - 1][0];
}

这里的推导公式应该要考虑到上一节点也会做买卖。
当买入股票时,可能会有之前买卖的利润,因此最大值的话用上一节点不持有股票的最大价值来计算才会是最大值。因此 dp[i][1] = Math.max(dp[i-1][1],dp[i-1][0] - prices[i]);
同不持有股票时,存在卖和不卖的情况,卖的情况要考虑到上一节点持有股票时的最大利润做加法 dp[i][0] = Math.max(dp[i-1][0],dp[i-1][1] + prices[i]);

今日收获&学习时长

今日学习1h,学习了下股票最佳时机。核心的逻辑就是要使用持有时的最大价值和不持有时的最大价值来计算。使用二维数组+动态规划五步骤做逻辑处理。

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

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

相关文章

Vue中插槽的简单使用

插槽 分类&#xff1a;默认插槽、具名插槽、作用域插槽 默认插槽&#xff1a;让父组件可以向子组件指定位置插入html结构&#xff0c;也是一种组件通信的方式&#xff0c;适用于父组件&#xff08;App&#xff09;>子组件(MyFooter) 默认插槽的App组件 <template>&…

WebofScience快速检索文献的办法

Web of Science为什么老是搜不到文章&#xff0c;原来是要在这个地方全部勾选 如果是搜标题的话&#xff0c;选Title&#xff0c;输入你要搜的文章标题 另外&#xff0c;也可以在浏览器直接搜文章标题&#xff0c;得到文章的DOI&#xff0c;然后选DOI&#xff0c;直接搜DOI也行…

红帽Redhat(liunx)连接虚拟机

一、xshell连接虚拟机的步骤 ①在Linux里面 ifconfig去查看网络的IP地址 setup设置IP地址 service network restart 重启网卡服务 ②在windows 打开网络和共享中心→更改适配器 仅主机&#xff1a;VMnet1 IPV4的IP Net模式&#xff1a;VMnet8 ③直…

中通快递查询,中通快递单号查询,批量删除不需要的快递单号

快递单号的管理现在是许多企业和个人日常工作中不可或缺的一部分&#xff0c;面对堆积如山的快递单号&#xff0c;如何快速、准确地处理成了许多人的难题。今天&#xff0c;我们将为大家带来一款强大的快递单号处理软件——快递批量查询高手&#xff0c;让你从此告别繁琐的手动…

SpringCloud-高级篇(十一)

&#xff08;1&#xff09;搭建Redis-主从架构 前面我们实现了Redis的持久化&#xff0c;解决了数据安全问题&#xff0c;但是还有需要解决的问题&#xff0c;下面学习Redis的主从集群&#xff0c;解决Redis的并发能力的问题 Redis的集群往往是主从集群&#xff0c;Redsi为什么…

MyBatis-基本概念

一、概念 概念MyBatis官方文档介绍&#xff1a;MyBatis is a first class persistence framework with support for custom SQL, stored procedures and advanced mappings. MyBatis eliminates almost all of the JDBC code and manual setting of parameters and retrieval …

【leetcode】字符串中的第一个唯一字符

题目描述 给定一个字符串 s &#xff0c;找到 它的第一个不重复的字符&#xff0c;并返回它的索引 。如果不存在&#xff0c;则返回 -1 。 用例 示例 1&#xff1a; 输入: s “leetcode” 输出: 0 示例 2: 输入: s “loveleetcode” 输出: 2 示例 3: 输入: s “aabb”…

游戏缺少x3daudio1_7.dll文件怎么办?x3daudio1_7.dll丢失总共有六个解决方法

导语&#xff1a;在计算机使用过程中&#xff0c;我们经常会遇到一些错误提示&#xff0c;其中之一就是“x3daudio1_7.dll丢失”。那么&#xff0c;x3daudio1_7.dll到底是什么文件呢&#xff1f;它的作用和影响又是什么呢&#xff1f;本文将为您详细介绍x3daudio1_7.dll的相关知…

linux cpu、memory 、io、网络、文件系统多种类型负荷模拟调测方法工具

目录 一、概述 二、stress介绍和使用 2.1 介绍 2.2 使用 三、stress-ng介绍和使用 3.1 介绍 3.2 使用 3.3 实例 四、sysbench 4.1 介绍 4.2 使用 五、lmbench 5.1 介绍 5.2 使用 一、概述 今天介绍两款cpu负荷调试工具,用来模拟多种类型的负载。主要用来模拟CPU…

LabVIEW开发自动光学焊点检测系统

LabVIEW开发自动光学焊点检测系统 LabVIEW于开发了一个自动光学焊点检测系统&#xff0c;旨在提高电子元件焊接的质量和效率。通过利用LabVIEW的高级视觉开发模块&#xff0c;该系统能够准确地识别和分类电路板上的不同焊点类型&#xff0c;如桥接、虚焊、漏焊和多锡。这一进步…

Java最大优先队列设计与实现

Java 学习面试指南&#xff1a;https://javaxiaobear.cn 1、API设计 类名MaxPriorityQueue构造方法MaxPriorityQueue(int capacity)&#xff1a;创建容量为capacity的MaxPriorityQueue对象成员方法private boolean less(int i,int j)&#xff1a;判断堆中索引i处的元素是否小…

Docker中swarm管理工具

Docker中swarm管理工具 1 安装swarm swarm是Docker自带的容器集群管理工具。 1.1 集群IP 主机名ip地址网卡名软件master192.168.108.201ens33Dockernode1192.168.108.202ens33Docker 修改主机名 # 管理节点&#xff0c;修改主机名 hostnamectl set-hostname master# 子节…

面试 React 框架八股文十问十答第一期

面试 React 框架八股文十问十答第一期 作者&#xff1a;程序员小白条&#xff0c;个人博客 相信看了本文后&#xff0c;对你的面试是有一定帮助的&#xff01;关注专栏后就能收到持续更新&#xff01; ⭐点赞⭐收藏⭐不迷路&#xff01;⭐ 1&#xff09;React 生命周期是怎样…

PHP代码审计之实战审代码篇2

4. 仔细观察如下代码&#xff0c;思考代码有什么缺陷&#xff0c;可能由此引发什么样的问题&#xff1f; <?php require_once("/home/rconfig/classes/usersession.class.php"); require_once("/home/rconfig/classes/ADLog.class.php"); require_onc…

neo4j-cypher语言使用

neo4j-cypher语言使用 neo4j的本质就是节点关系。节点是用小括号来表示&#xff0c;&#xff08;节点&#xff1a;节点标签 {属性名称&#xff1a;属性值}&#xff09;with 本质是with(变量) 传送到下一个语句&#xff0c;with 子处理(变量), with 查询return 变量。unwind 本质…

【二】使用create-vue创建vue3的helloworld项目(推荐)

create-vue 官网&#xff1a;快速上手 | Vue.js create-vue 是 Vue3 的专用脚手架&#xff0c;使用 vite 创建 Vue3 的项目&#xff0c;也可以选择安装需要的各种插件&#xff0c;使用更简单。 1、使用方式 npm create vuelatest这个命令会安装和执行 create-vue&#xff0…

k8s的yaml文件中的kind类型都有哪些?(清单版本)

在操作kubenates的过程中&#xff0c;我们接触到的yaml文件中的kind类型有很多。他们代表了kubenate的不同类型的对象&#xff0c;了解了kind的类型&#xff0c;也就相当于了解了k8s都有哪些类型的对象。 类型清单及概要说明 序号类型简述1Pod一个Kubernetes中最基本的资源类型…

排序算法记录

冒泡排序 public class BubbleSorting20230704 {public static void main(String[] args) {int[] numbers new int[]{2,3,1,5,4};for(int i0;i<numbers.length;i){for (int j0;j<numbers.length-1-i;j){if(numbers[j]>numbers[j1]){int temp numbers[j];numbers[j]…

【MATLAB源码-第105期】基于matlab的4PAM调制解调仿真,输出误码率和误符号曲线并且和理论值对比。

操作环境&#xff1a; MATLAB 2022a 1、算法描述 4PAM&#xff08;4-Pulse Amplitude Modulation&#xff0c;4脉冲幅度调制&#xff09;是一种数字调制技术&#xff0c;它通过改变载波信号的幅度来表示数据。在4PAM中&#xff0c;载波的幅度可以采用四种不同的水平&#xf…

天翼云搭建AIGC开发环境综合教程

一、英伟达环境安装主要流程 1、下载安装对应系统版本nVidia驱动程序安装验证 2、CUDA开发套件安装验证 3、深度学习框架安装验证MiniConda3PyTorch 4、容器化CUDA环境安装验证 5、cuDNN深度学习优化驱动安装CNN训练验证 6、制作天翼云主机私有镜像 7、分享镜像给其他用…