代码随想录刷题day32|买卖股票的最佳时机II跳跃游戏跳跃游戏II

文章目录

  • day32学习内容
  • 一、买卖股票的最佳时机II
    • 1.1、思路
    • 1.2、代码-正确写法
      • 1.2.1、如何理解result += Math.max(prices[i] - prices[i - 1], 0)
        • 算法逻辑
  • 二、跳跃游戏
    • 2.1、思路
    • 2.2、正确写法1
      • 2.2.1、 如何理解上面这段代码
        • 逻辑详解
      • 2.2.2、为什么要i + nums[i]?
        • 解释
        • 为什么重要
      • 2.2.3、还是看不懂?举个具体例子帮助理解
  • 三、跳跃游戏II
    • 3.1、思路
    • 3.2、正确写法1
      • 3.2.1、如何理解这段代码
      • 3.2.2 、如何理解i == end
  • 总结
    • 1.感想
    • 2.思维导图


day32学习内容

day32主要内容

  • 买卖股票的最佳时机II
  • 跳跃游戏
  • 跳跃游戏II

声明
本文思路和文字,引用自《代码随想录》

一、买卖股票的最佳时机II

122.原题链接

1.1、思路

假如第 0 天买入,第 3 天卖出,那么利润为:prices[3] - prices[0]。

相当于(prices[3] - prices[2]) + (prices[2] - prices[1]) + (prices[1] - prices[0])。
也就是prices[3] - prices[0] = 每天的利润之和。

只收集每天的正利润,收集正利润的区间,就是股票买卖的区间,而我们只需要关注最终利润,不需要记录区间。

此题贪心在哪里?只收集正利润就是贪心所贪的地方!

局部最优:收集每天的正利润,全局最优:求得最大利润。

1.2、代码-正确写法

class Solution {public int maxProfit(int[] prices) {int result = 0;for (int i = 1; i < prices.length; i++) {// 只取正利润,和0取最大值,是负数直接加0,是正数就加prices[i] - prices[i - 1]result += Math.max(prices[i] - prices[i - 1], 0);}return result;}
}

1.2.1、如何理解result += Math.max(prices[i] - prices[i - 1], 0)

算法逻辑
  • int result = 0;: 初始化变量result用于累积总利润,初始值设为0。
  • for (int i = 1; i < prices.length; i++) { ... }: 通过一个循环遍历prices数组(从第二个元素开始,即i = 1),比较连续两天的价格,以决定是否进行交易。
    • result += Math.max(prices[i] - prices[i - 1], 0);: 这行代码是算法的核心。它计算连续两天的价格差(prices[i] - prices[i - 1]),如果价格差是正的,表示第i-1天买入、第i天卖出可以获得利润,所以将这个正的价格差累加到result中;如果价格差是负的或零,表示没有利润(或亏损),则不进行操作(通过Math.max(…, 0)实现,即如果价格差小于0,则加0,否则加价格差)。

二、跳跃游戏

55.原题链接

2.1、思路

此段文字摘抄字代码随想录
https://www.programmercarl.com/0055.%E8%B7%B3%E8%B7%83%E6%B8%B8%E6%88%8F.html#%E6%80%9D%E8%B7%AF

刚看到本题一开始可能想:当前位置元素如果是 3,究竟是跳一步呢还是两步呢还是三步呢,究竟跳几步才是最优呢?
其实跳几步无所谓,关键在于可跳的覆盖范围!
不一定非要明确一次究竟跳几步,每次取最大的跳跃步数,这个就是可以跳跃的覆盖范围。
这个范围内,不用管是怎么跳的,反正一定可以跳过来。
那么这个问题就转化为跳跃覆盖范围究竟可不可以覆盖到终点
每次移动取最大跳跃步数(得到最大的覆盖范围),每移动一个单位,就更新最大覆盖范围。

2.2、正确写法1

class Solution {public boolean canJump(int[] nums) {if (nums.length == 1) {return true;}// 初始化覆盖范围,为什么为0?因为开始没有调,所以是0int coverRange = 0;// 在覆盖范围内更新coverRangefor (int i = 0; i <= coverRange; i++) {// 当前为位置i,最大可达位置为i+nums[i]coverRange = Math.max(coverRange, i + nums[i]);if (coverRange >= nums.length - 1) {return true;}}return false;}
}

2.2.1、 如何理解上面这段代码

逻辑详解
  1. 特殊情况处理:

    • if (nums.length == 1) { return true; }: 如果数组长度为1,意味着我们已经在最后一个位置上,不需要任何跳跃就已经达成条件,因此返回true
  2. 初始化覆盖范围:

    • int coverRange = 0;: 初始化变量coverRange,表示当前能覆盖到的最远距离。初始值为0,因为我们还没开始跳跃。
  3. 循环更新覆盖范围:

    • for (int i = 0; i <= coverRange; i++) {...}: 遍历数组nums,但只在当前覆盖范围内进行遍历。这是因为,如果某个位置超出了当前的覆盖范围,那么这个位置就无法被到达。
    • coverRange = Math.max(coverRange, i + nums[i]);: 在每一步,更新coverRange。这里i + nums[i]计算的是如果从位置i进行跳跃,最远能到达的位置。Math.max确保coverRange总是存储当前能到达的最远位置。
    • if (coverRange >= nums.length - 1) { return true; }: 如果在任何时刻coverRange超过或等于数组的最后一个位置的索引,那么说明可以到达数组的最后一个位置,方法返回true
  4. 无法到达最后位置:

    • 如果循环结束,意味着即使尽可能地跳跃,也无法覆盖到数组的最后一个位置,此时方法返回false

2.2.2、为什么要i + nums[i]?

在这个问题中,i + nums[i]的计算是为了确定从当前位置i开始,最远能跳到哪里。这里的逻辑是基于题目的规则:你在位置i时,可以跳跃的最大长度是nums[i]。因此,如果你现在处于位置i,那么你最远可以跳到i + nums[i]这个位置。

解释
  • i(当前位置): 表示你现在所在数组的位置。
  • nums[i](跳跃能力): 数组nums中的每个元素表示从那个位置最多可以向前跳跃的步数。因此,nums[i]表示从位置i最多可以跳跃的步数。
  • i + nums[i](最远可达位置): 当你在位置i时,向前跳nums[i]步,你将会到达的位置。这个计算显示了从当前位置出发,依据你的最大跳跃能力,能够到达的最远位置。
为什么重要

在解决“跳跃游戏”问题时,我们需要不断地更新在数组中能够到达的最远位置。通过比较coverRange(当前能覆盖到的最远距离)和i + nums[i](从当前位置i出发能到达的最远距离),我们可以确保coverRange始终保持在最大值。这是因为,在实际操作中,我们可能不需要每次都跳到最大距离,但了解能跳到的最远距离对于判断是否能到达数组末尾至关重要。

这种方式允许我们在遍历数组的过程中,用最小的步数高效地更新能够到达的最远位置,从而判断是否能够到达数组的最后位置。如果在某一步coverRange已经大于等于数组的最后一个索引,那么就意味着我们可以到达数组的最后位置。这是一个运用贪心算法思想的典型例子,通过局部最优选择(每一步尽可能跳得远),来达到全局的最优解(到达数组末尾)。

2.2.3、还是看不懂?举个具体例子帮助理解

假设有一个数组nums = [2, 3, 1, 1, 4],我们逐步分析代码的执行过程:

  1. 初始覆盖范围coverRange = 0,表示在开始时我们还没有开始移动,因此覆盖范围为0。
  2. 开始遍历数组,i = 0时,nums[0] = 2,这意味着从位置0,我们最多可以向前跳2步。因此,coverRange更新为max(0, 0 + 2) = 2。现在覆盖范围扩展到了索引2的位置。
  3. 下一步,i = 1nums[1] = 3,从位置1我们可以跳3步,这意味着我们可以达到更远的位置,即coverRange = max(2, 1 + 3) = 4。现在覆盖范围扩展到了数组的末尾。
  4. 由于覆盖范围已经达到或超过了数组的最后一个位置(覆盖范围索引从0开始,所以数组的最后一个位置是nums.length - 1 = 4),循环会提前终止,并返回true,表示我们可以跳到数组的最后位置。

三、跳跃游戏II

45.原题链接

3.1、思路

  • 翻译成人话就是计算跳跃到终点的最少步数。

3.2、正确写法1

class Solution {public int jump(int[] nums) {int result = 0;int end = 0;int temp = 0;// 在可以覆盖的范围内遍历,且只有当我们还没有到达数组末尾时才继续。for (int i = 0; i <= end && i < nums.length - 1; i++) {// 计算当前最大可覆盖范围temp = Math.max(i + nums[i], temp);// 遍历到了当前跳跃可以覆盖的最远距离下标,还没有到数组的终点位置,需要继续往下走1步。if (i == end) {end = temp;result++;}}return result;}
}

3.2.1、如何理解这段代码

理解这段代码的关键在于理解endtemp两个变量的作用:

  • end变量表示当前跳跃可以覆盖的最远距离下标。初始时,由于我们还没有开始跳跃,它被设置为0。
  • temp变量表示下一次跳跃可以覆盖的最远距离下标。它用于在遍历过程中不断更新我们可以达到的最远距离。

算法执行的流程如下:

  1. 初始化result为0,表示跳跃次数;end为0,表示当前覆盖的最远距离下标;temp为0,表示下一步覆盖的最远距离下标。
  2. 遍历数组元素(注意,循环的条件是i <= end && end < nums.length - 1,意味着我们会在可以覆盖的范围内遍历,且只有当我们还没有到达数组末尾时才继续)。
  3. 在每一次遍历中,我们更新tempi + nums[i]temp中的较大值,这表示如果从当前位置i跳跃,我们能到达的最远位置。
  4. 当遍历到当前覆盖的最远距离end时(即i == end),说明我们需要进行一次跳跃以到达更远的位置。这时,我们将end更新为temp(因为temp是我们在当前覆盖范围内可以达到的最远距离),并将跳跃次数result增加1。
  5. 重复步骤3和4,直到覆盖范围包含数组的最后一个位置,这时跳出循环。
  6. 返回result作为结果,即到达数组末尾所需的最少跳跃次数。

通过这种方式,代码贪心地在每一步跳跃中都尽可能向前跳到最远的位置,从而确保跳跃次数最少。

3.2.2 、如何理解i == end

在这段代码中,i == end这个条件用于判断是否遍历到了当前跳跃可以覆盖的最远距离下标。这里的end变量表示在当前跳跃次数下,我们可以到达的最远位置的索引。每当i(当前遍历到的位置的索引)与end相等时,意味着我们已经到达了当前跳跃能够覆盖的最远范围的边界。此时有两个关键点需要注意:

  1. 跳跃次数的增加:当i达到了当前的end时,我们需要进行一次新的跳跃(即增加跳跃次数result),因为我们已经尽可能地利用了当前跳跃的能力,而要进一步前进,就必须开始一次新的跳跃。

  2. 更新下一次的最远距离:在每次遍历过程中,我们通过比较tempi + nums[i]来更新下一次跳跃可以到达的最远距离。而当i == end时,即我们达到了当前能达到的最远距离,这时我们就需要把end更新为temp,因为temp此时代表了下一次跳跃可以到达的最远距离。

举个具体例子:

假设数组是 nums = [2, 3, 1, 1, 4]

初始时,我们在位置0,end = 0,表示当前跳跃能达到的最远距离(这里是指下标,下标从0开始),temp = 0表示下一步跳跃可以到达的最远距离,result = 0表示跳跃次数。

  1. 第一轮循环: 初始i = 0end = 0

    • i = 0时,nums[0] = 2,表示从位置0出发最多可以向前跳2步。所以,temp = max(temp, i + nums[i]) = max(0, 0 + 2) = 2。这意味着在当前这一跳中,我们可以到达的最远是下标为2的位置。
    • 在这轮循环的结束时(i == end),意味着我们已经达到了当前跳跃能到达的最远位置。此时我们将end更新为temp的值(也就是2),表示下一次跳跃的最远范围。同时,result++表示完成了一次跳跃。
  2. 第二轮循环: 现在,i会从1继续增加,直到i = end(此时end = 2)。

    • i = 1时,nums[1] = 3,这意味着从位置1出发最多可以向前跳3步,因此temp更新为max(2, 1 + 3) = 4。现在temp表示我们从当前所有检查的位置出发能到达的最远位置是下标4。
    • i = 2时,即i达到了当前end的值,这标志着需要进行一次新的跳跃。因为temp此时为4,表示下一次跳跃能达到的最远位置已经是数组的最后了。我们将end更新为temp,同时result++

通过上面的过程,我们完成了两次跳跃就到达了数组的最后一个位置,因此函数返回result = 2

这个例子中,“当i增加到end的值时,说明我们已经达到了当前跳跃能够到达的最远位置”这句话的含义是:在每次的跳跃过程中,当我们遍历到end所标记的位置时,意味着我们已经利用当前这一跳的能力达到了最大范围,此时需要基于temp(记录了从起点到当前点的所有可能的最远跳跃点)的值来开始下一跳,并且这一跳的结束点(即下一次的end)就是当前的temp

总结

1.感想

  • 跳跃游戏II这鬼题目都看不懂,还是看卡尔的翻译一下才看得懂题目,题意不说人话的,翻译成人话就是计算跳跃到终点的最少步数。
  • 跳跃游戏II写不出来,抄的题解。。

2.思维导图

本文思路引用自代码随想录,感谢代码随想录作者。

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

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

相关文章

亚马逊认证考试系列 - 知识点 - 什么是VPC

VPC指的是虚拟私有云&#xff08;Virtual Private Cloud&#xff09;&#xff0c;它是在公共云环境中创建一个逻辑隔离的虚拟网络环境。VPC可以让您在云中划分一个私有区域并且在这个区域内运行您的资源&#xff0c;比如虚拟机实例、数据库实例等。VPC可以帮助您实现网络安全性…

如何成为顶尖程序员?

如何成为顶尖程序员&#xff1f; 程序员是一种特殊的职业&#xff0c;但为什么大多数程序员无法达到顶尖水平&#xff1f;本文探讨了几个可能的原因&#xff0c;包括缺乏热情和动力、基础和原理的不足、实践和经验的匮乏&#xff0c;以及思考和创新的欠缺。了解这些原因可以帮助…

基于SpringBoot+MyBatis+Vue的电商智慧仓储管理系统的设计与实现(源码+LW+部署+讲解)

前言 博主简介&#x1f468;&#x1f3fc;‍⚕️&#xff1a;国内某一线互联网公司全栈工程师&#x1f468;&#x1f3fc;‍&#x1f4bb;&#xff0c;业余自媒体创作者&#x1f4bb;&#xff0c;CSDN博客专家&#x1f3c6;&#xff0c;Java领域优质创作者&#x1f4d5;&#x…

Redis中文乱码问题

最近排查问题&#xff0c;发现之前的开发将日志写在redis缓存中&#xff08;不建议这样做&#xff09;&#xff0c;我在查看日志的时候发现没办法阅读&#xff0c;详细是这样的&#xff1a; 查阅资料后发现是进制问题&#xff0c;解决方法是启动客户端的时候将redis-cli改为red…

【go从入门到精通】if else 条件控制

作者简介&#xff1a; 高科&#xff0c;先后在 IBM PlatformComputing从事网格计算&#xff0c;淘米网&#xff0c;网易从事游戏服务器开发&#xff0c;拥有丰富的C&#xff0c;go等语言开发经验&#xff0c;mysql&#xff0c;mongo&#xff0c;redis等数据库&#xff0c;设计模…

python笔记基础--文件和存储数据(7)

目录 1.从文件中读取数据 2.写入文件 3.存储数据 3.1使用json.dump()和json.load() 3.2保存和读取用户生成的数据 3.3重构 1.从文件中读取数据 读取整个文件 with open(data.txt) as file_object: contents file_object.read()print(contents)print(contents.rstrip…

电脑安装双系统windows和ubuntu server

1.创建Ubuntu-server的启动盘 首先要从官网下载Ubuntu-server18.04的ISO文件&#xff0c;用rufs烧录到U盘。如下所示 2. 磁盘分区 在windows创建两个盘&#xff08;linuxboot 和linuxroot&#xff09;&#xff0c;后面一个一个用于boot&#xff0c;一个用于root. 3.开机U盘启…

Flutter学习10 - Json解析与Model使用

对于网络请求返回的 Json 数据&#xff0c;一般会进行如下解析&#xff1a; 将 Json String 解析为 Map<String, dynamic>将 Json String 解析为 Dart Model 发起一个返回 Json String 的网络请求 import package:http/http.dart as http;void main() {_doGet(); }_do…

用好商用无人自助咖啡机,真正实现“AI智能”制饮!

随着科技的不断进步和智能化技术的广泛应用&#xff0c;商用无人自助咖啡机作为餐饮行业的新宠&#xff0c;正逐渐改变着我们的生活方式和消费体验。通过结合人工智能技术&#xff0c;这些无人自助咖啡机正在实现真正的“AI智能”制饮&#xff0c;为消费者带来全新的咖啡体验。…

Qt 项目使用visual studio 进行开发调试

https://marketplace.visualstudio.com/items?itemNameTheQtCompany.QtVisualStudioTools2015 https://devblogs.microsoft.com/cppblog/bring-your-existing-qt-projects-to-visual-studio/ 正常Qt开发中&#xff0c;使用Qt Creator 进行windows下MSVC编译器的调试是一件挺麻…

【C++之string类】

C学习笔记---009 C知识string类1、String类1.1、为什么要学习string类&#xff1f;1.2、string的背景介绍1.3、string类的小结 2、标准库中的string类3.1、string类的常用接口说明3.2、string类常用接口的应用13.3、string类常用接口的应用23.4、string类常用接口的应用33.5、s…

最常考的设计模式之一---单例模式

软件开发中有很多常见的 "问题场景". 针对这些问题场景, 大佬们总结出了一些固定的套路,这些套路就被称为设计模式 而我们今天要介绍的就是设计模式中的单例模式 单例模式的定义 单例模式是一种常见的设计模式&#xff0c;它确保一个类只有一个实例&#xff0c;并提…

Medium 级别反射型 XSS 攻击演示(附链接)

环境准备 如何搭建 DVWA 靶场保姆级教程&#xff08;附链接&#xff09;https://eclecticism.blog.csdn.net/article/details/135834194?spm1001.2014.3001.5502 测试 打开靶场找到该漏洞页面 先右键检查输入框属性 跟 Low 级别是一样的&#xff0c;所以咱们直接输入带 HTM…

如何查看局域网内所有的ip和对应的mac地址

1、windows下查看 方法一、 按快捷键“winr”打开运行界面&#xff0c;输入“CMD”回车: 输入以下命令&#xff1a; for /L %i IN (1,1,254) DO ping -w 1 -n 1 192.168.0.%i 其中 192.168.0.%i 部分要使用要查询的网段&#xff0c;比如 192.168.1.%i 192.168.137.%i 172.16.2…

AI修复老照片的一些参数设置

很久没更新CSDN文章了&#xff0c;这次给粉丝带来老照片修复流程 1>用ps修图 图章工具 笔刷 画笔修复 2>高清放大 3>lineattile 重绘 4>上色 具体可参考我的B站视频。 下面是一些笔记。 best quality,masterpiece,photorealistic,8k,ultra high res,solo,ext…

概念解析 | 现象揭秘:经验模态分解的奥秘

注1:本文系"概念解析"系列之一,致力于简洁清晰地解释、辨析复杂而专业的概念。本次辨析的概念是:经验模态分解(Empirical Mode Decomposition, EMD) 概念解析 | 现象揭秘:经验模态分解的奥秘 Decomposing Signal Using Empirical Mode Decomposition — Algorith…

记录一次流相关故障

记录一次流相关故障 1、项目中有个JSON字典文件&#xff0c;通过流的方式加载进来&#xff0c;写了个输入流转字符串的方法&#xff0c;idea开发环境下运行一切正常&#xff0c;打成jar或者war包运行时&#xff0c;只能加载出部分数据&#xff0c;一开始怀疑过运行内存分配过小…

python基础练习题4

目录 1、求一个十进制的数值的二进制的0、1的个数 2、实现一个用户管理系统&#xff08;要求使用容器保存数据&#xff09; [{name: xxx, pass: xxx, ……},{},{}] 3、求1~100之间不能被3整除的数之和 4、给定一个正整数N,找出1到N&#xff08;含&#xff09;之间所有质数的…

Spring MVC入门(4)

请求 获取Cookie/Session 获取Cookie 传统方式: RequestMapping("/m11")public String method11(HttpServletRequest request, HttpServletResponse response) {//获取所有Cookie信息Cookie[] cookies request.getCookies();//打印Cookie信息StringBuilder build…

电源变压器电感的工艺结构原理及选型参数总结

🏡《总目录》 目录 1,概述2,工作原理3,结构特点3.1,铁芯3.2,线圈3.3,套管3.4,外壳4,工艺流程4.1,准备原材料4.2,制作线圈框架4.3,选择绝缘材料4.4,选择漆包线4.5,绕制线圈