DAY37:贪心算法(四)跳跃游戏+跳跃游戏Ⅱ

这篇具有很好参考价值的文章主要介绍了DAY37:贪心算法(四)跳跃游戏+跳跃游戏Ⅱ。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

55.跳跃游戏

给定一个非负整数数组 nums ,你最初位于数组的 第一个下标

数组中的每个元素代表你在该位置可以跳跃的最大长度。

判断你是否能够到达最后一个下标。

示例 1:

输入:nums = [2,3,1,1,4]
输出:true
解释:可以先跳 1 步,从下标 0 到达下标 1, 然后再从下标 13 步到达最后一个下标。

示例 2:

输入:nums = [3,2,1,0,4]
输出:false
解释:无论怎样,总会到达下标为 3 的位置。但该下标的最大跳跃长度是 0 , 所以永远不可能到达最后一个下标。

提示:

  • 1 <= nums.length <= 3 * 104
  • 0 <= nums[i] <= 105

思路

游戏大致规则如下图。每一步代表着能跳跃的最大长度。能通过不同的步数组合,跳到最后一个下标就输出true。

DAY37:贪心算法(四)跳跃游戏+跳跃游戏Ⅱ,贪心算法,算法,c++,leetcode
本题直接看每个元素应该跳几步很难解出来,需要去看覆盖范围。如下图所示。

也就是说,不要管跳几步,不看具体是怎么跳的,只看每个数字的覆盖范围。如果是3,就覆盖后面三个数,如果是2,就覆盖后面两个数。

DAY37:贪心算法(四)跳跃游戏+跳跃游戏Ⅱ,贪心算法,算法,c++,leetcode

完整版

  • 在已有的覆盖范围内遍历每一个元素,得到新的可跳跃的步数,增加覆盖范围,取最大的覆盖范围
class Solution {
public:
    bool canJump(vector<int>& nums) {
        int cover=0;
        if(nums.size()==1) return true;
        //此时是i<=cover而不是i<=nums.size(),因为是在覆盖范围内部遍历
        for(int i=0;i<=cover;i++){
            //找范围内最大的cover数值
            cover = max(i+nums[i],cover);
            if(cover>=nums.size()-1){
                return true;
            }
        }
        //如果遍历完了cover还没找到
        return false;
    }
};

这种思路还是比较难以理解的话,可以看下面的图进行对比。

DAY37:贪心算法(四)跳跃游戏+跳跃游戏Ⅱ,贪心算法,算法,c++,leetcode
由上图可知,我们不需要知道他的跳跃路径,只需要看cover内部,最大的覆盖范围就行了!

总结

这道题目关键点在于:不用拘泥于每次究竟跳几步,而是看覆盖范围覆盖范围内一定是可以跳过来的,不用管是怎么跳的

从这道题也可以看出来贪心并没有什么套路,只能多接触,没接触的话想不出来,接触之后下次就要考虑这种思维。

45.跳跃游戏Ⅱ

视频课程:贪心算法,最少跳几步还得看覆盖范围 | LeetCode: 45.跳跃游戏II_哔哩哔哩_bilibili

  • 本题解法也不太好想,最好结合视频课程和画图一起理解。

给定一个长度为 n 的 0 索引整数数组 nums。初始位置为 nums[0]

每个元素 nums[i] 表示从索引 i 向前跳转的最大长度。换句话说,如果你在 nums[i] 处,你可以跳转到任意 nums[i + j] 处:

  • 0 <= j <= nums[i]
  • i + j < n

返回到达 nums[n - 1] 的最小跳跃次数。生成的测试用例可以到达 nums[n - 1]。

示例 1:

输入: nums = [2,3,1,1,4]
输出: 2
解释: 跳到最后一个位置的最小跳跃数是 2。
     从下标为 0 跳到下标为 1 的位置,跳 1 步,然后跳 3 步到达数组的最后一个位置。

示例2:

输入: nums = [2,3,0,1,4]
输出: 2

提示:

  • 1 <= nums.length <= 104
  • 0 <= nums[i] <= 1000
  • 题目保证可以到达 nums[n-1]

思路

本题和跳跃游戏的区别是,本题需要输出最少跳几步,才能跳到终点的位置。

此时也不能每一步都跳最大值,因为最少的情况并不一定是每一步都跳了当前的最大值

本题依然是用覆盖范围的思想,每跳一步,尽可能地增加覆盖范围只要覆盖范围覆盖了终点,说明用当前步数就可以跳到终点位置。

DAY37:贪心算法(四)跳跃游戏+跳跃游戏Ⅱ,贪心算法,算法,c++,leetcode

完整版

  • 本题的条件,也是i<=cover,没必要用i<=nums.size()
  • 但是本题多了一步next,也就是下一步的值,是记录cover内部遍历过的下一步的最大值
  • 注意next是记录的下一步能达到的最大的下标结果值,包括了数值很大但是本身很靠前的情况。
class Solution {
public:
    int jump(vector<int>& nums) {
        //如果数组长度只有1,那么就是0步
        if(nums.size()==1) return 0;
        int cover=0;
        //统计下一步的覆盖范围,是cover内的最大值
        int next=0;
        int result=0;
        //本题的条件,也是i<=cover,没必要用i<=nums.size()
        for(int i=0;i<=cover;i++){
            next=max(i+nums[i],next);//只记录遍历过的数字里,最大的下一步的下标值
            if(i==cover){//移动到了当前的终点
                if(i<nums.size()-1){//如果没到头,就再走一步
                    result++;
                    cover=next;//启动下一步覆盖范围,一旦覆盖到终点,立即break,因为result已经++了
                    if(cover>=nums.size()-1){
                    	break;
                    }
                }
                //如果到头了,也就是当前的cover已经到终点了
                else
                    break;
            }
        }
        return result;
    }
};
为什么next覆盖到了终点可以直接break,不用加上最后一步

本题的逻辑是,当达到cover的时候,result直接跳出循环。

例如输入[2,3,1,1,4],cover的时候遍历到nums[2]的时候,加上next已经满足条件,直接break出去,并没有对result再次进行++操作。

这是因为最开始的时候cover=0,而i也=0,也就是说最开始的时候已经累积一步了!由于我们把长度为1只有一个数字的情况单独放了,所以遍历到下面一定是长度>=2的,至少要走一步。相当于最开始已经累积一步了。

逻辑梳理

在这个算法中,每一次跳跃实际上都是在覆盖范围(cover)的边界上进行的,而不是在覆盖范围内部。

所以当我们第一次进入循环时,i等于cover(都是0),并且这时我们实际上已经做了第一次“跳跃”,也就是从起点跳到了能够覆盖的最远距离,因此result增加1。然后,每一次当i再次等于cover时,我们就会进行下一次跳跃,也就是从当前覆盖范围的边界跳到下一次能够到达的最远位置(也就是max(i+nums[i])

当遍历到cover的时候,如果cover已经覆盖到了数组的末尾,那么我们就直接跳出循环,因为这表示我们已经跳到了终点,没有必要再跳了。但是在跳出循环之前,我们已经把这次跳跃计入了result中,所以不会漏掉最后一次跳跃

总结

这道题比起跳跃游戏Ⅰ难了很多,本题关键在于,以最小的步数增加最大的覆盖范围,直到覆盖范围覆盖了终点,这个范围内最小步数一定可以跳到,不用管具体是怎么跳的,也不用纠结于一步究竟跳一个单位还是两个单位。

这也是一个贪心策略,我们试图在每次跳跃中到达能覆盖更远的位置。所以在每一轮循环中,我们尝试遍历当前的覆盖范围(cover)内的所有位置,并在这个范围内找到能够跳跃到的最远位置的下标,这个最远的距离我们保存在变量next中,将next与最后一个下标对比。

当数组长度大于1时,我们实际上是在循环开始时就已经“预先”计算了一次跳跃,所以当next超出范围,直接break,不会漏掉任何一次跳跃。文章来源地址https://www.toymoban.com/news/detail-524242.html

到了这里,关于DAY37:贪心算法(四)跳跃游戏+跳跃游戏Ⅱ的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【LeetCode题目详解】第八章 贪心算法 part06 738.单调递增的数字 968.监控二叉树 (day37补)

    当且仅当每个相邻位数上的数字  x  和  y  满足  x = y  时,我们称这个整数是 单调递增 的。 给定一个整数 n ,返回 小于或等于 n 的最大数字,且数字呈 单调递增 。 示例 1: 示例 2: 示例 3: 提示: 0 = n = 109 # 暴力解法 题意很简单,那么首先想的就是暴力解法了,来我替大家

    2024年02月10日
    浏览(39)
  • leetcode55.跳跃游戏 【贪心】

    题目: 给你一个非负整数数组  nums  ,你最初位于数组的  第一个下标  。数组中的每个元素代表你在该位置可以跳跃的最大长度。 判断你是否能够到达最后一个下标,如果可以,返回  true  ;否则,返回  false  。 示例: 示例 1: 示例 2: 思路: 不能遍历依次遍历每

    2024年02月10日
    浏览(38)
  • 团灭LeetCode跳跃游戏(相关话题:贪心,BFS)

    目录 LeetCode55跳跃游戏 LeetCode45. 跳跃游戏 II LeetCode1306. 跳跃游戏 III LeetCode1345. 跳跃游戏 IV 解题总结 LeetCode55跳跃游戏 给定一个非负整数数组  nums  ,你最初位于数组的  第一个下标  。 数组中的每个元素代表你在该位置可以跳跃的最大长度。 判断你是否能够到达最后一

    2023年04月08日
    浏览(44)
  • 【算法刷题 | 贪心算法04】4.26(跳跃游戏、跳跃游戏||)

    给你一个非负整数数组 nums ,你最初位于数组的 第一个下标 。数组中的每个元素代表你在该位置可以跳跃的最大长度。 判断你是否能够到达最后一个下标,如果可以,返回 true ;否则,返回 false 。 示例一: 示例二: 6.2.1贪心思路 一般思路:当前位置元素如果是 3,我究竟

    2024年04月27日
    浏览(38)
  • 算法记录 | Day37 贪心算法

    思路: 1.一旦出现strNum[i - 1] strNum[i]的情况(非单调递增),首先想让strNum[i - 1]–,然后strNum[i]给为9,这样这个整数就是89,即小于98的最大的单调递增整数。 2.向后遍历 从前向后遍历的话,遇到strNum[i - 1] strNum[i]的情况,让strNum[i - 1]减一,但此时如果strNum[i - 1]减一了,可能

    2023年04月22日
    浏览(31)
  • 贪心算法-跳跃游戏

    给你一个非负整数数组  nums  ,你最初位于数组的  第一个下标  。数组中的每个元素代表你在该位置可以跳跃的最大长度。 判断你是否能够到达最后一个下标,如果可以,返回  true  ;否则,返回  false  。 示例 1: 示例 2: 提示: 1 = nums.length = 104 0 = nums[i] = 105 贪心在

    2024年04月27日
    浏览(33)
  • 跳跃游戏【贪心算法】

    跳跃游戏 给你一个非负整数数组 nums ,你最初位于数组的 第一个下标 。数组中的每个元素代表你在该位置可以跳跃的最大长度。 判断你是否能够到达最后一个下标,如果可以,返回 true ;否则,返回 false 。在这里插入图片描述

    2024年02月11日
    浏览(37)
  • 贪心算法-01:跳跃游戏

    贪心算法是动态规划的一个特例,相对于动态规划,使用贪心算法需要满足更多条件,但是效率比动态规划要高。 贪心选择的性质就是:每一步都做出一个局部最优解,最终的结果就是全局最优。不过这是一种特殊性质,只有一部分问题拥有这个性质。 比如面前放有100张人

    2024年01月22日
    浏览(41)
  • Day 37 贪心算法 6

    代码随想录  1. 思路 从后向前判断,如果不呈现单调递增的状态,后一位变成9,前一位-1。这里局部最优是每两位的最优解,从后向前线性遍历能得到全局最优。 但是有一点没有想清楚 。如果出现了上述的两位数倒序情况,之后的所有数字都应该变成9。例如52583,最小的递

    2024年02月01日
    浏览(37)
  • 贪心算法-跳跃游戏问题(java)

    1.1 题目描述 输入是一个非负整数数组nums,数组元素nums[i]代表你站的位置i最多能够向前跳几步。现在你站的第一个位置nums[0],请问能否跳到最后一个位置。 举例: nums = [2,3,1,1,4] 这个就可以跳到最后,返回true nums = [3,2,1,0,4]这个就无法跳到最后,返回false 1.2解题思路: 我们每

    2024年02月05日
    浏览(49)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包