算法通过村第十七关-贪心|黄金笔记|跳跃游戏

文章目录


前言


提示:曾走过山,走过水,其实只是借助他们走过我的生命;我看着天,看着地,其实只是借助它们确定我的位置;我爱这她,爱着你,其实只不过借助别人实现了我的爱欲。 --史铁生《务虚笔记》

跳跃问题也是常考的类型之一,这里务必学习以下,我们就接着往下看。

💕😎💡⭐🥰🌰😭😥😒💣❔😂🤩👌👍🤖✅🤔

跳跃游戏

参考题目地址:55. 跳跃游戏 - 力扣(LeetCode)

如果当前位置元素如果是3,我究竟是要跳几步呢?其实这不是考虑的重点,关键在于是否最终可以到达重点,而不是每一步跳到哪里,而是尽可能的跳跃到最远的位置,看看最多的可以覆盖到哪里,只要不断更新覆盖的距离没最终覆盖到结尾就可以了。

从上图可以看出:

第一组:

3可以覆盖到{2,1,0},2可以覆盖到{1,0},1可以覆盖到{0},最终无法达到4.

第二组:

2可以覆盖到{3,1},3可以覆盖到{1,1,4},1可以覆盖到{1},1可以覆盖到{4}.到达终点。可达路径有

3条,{2,1,1 ,4}和{2,3,1,1,4}两种走法。

我们可以定义一个cover表示最远可以到达的方位,也就是i每次移动只能在cover的范围内移动,每次一档,cover得到该元素的值(新的覆盖范围)的补充,让i继续移动下去,儿cover每次按照下面的结果判断,如果cover大于等于最终下标直接返回true就可以了。

java 复制代码
cover = max(该元素可以覆盖到的范围,该元素数值补充后的范围)

针对这个判断:我们再看下序列图:

第二组数据:

nums[0] = 2,此时cover = 2 能覆盖到{3.1}两个元素。

继续第二个元素,nums[1] = 3,此时能继续覆盖的范围就是1 + 3 ,可以覆盖到{1,1,4}三个位置,此时cover = 2,而该元素数值的补充后的范围值1 + 3 = 4,所以新的cover = max{4,2}.当然在这里已经可以结束了,cover >= nums.length- 1.

其他的情况也是如此,我们看下代码实现:

java 复制代码
    /**
     * 跳跃游戏
     * @param nums
     * @return
     */
    public static boolean canJump(int[] nums) {
        if (nums.length == 1){
            return true;
        }
        // 初始覆盖值0,也就从下标0开始遍历
        int cover = 0;
        for(int i = 0; i <= cover; i++){
            cover = Math.max(cover, i + nums[i]);
            // 超过就返回
            if (cover >= nums.length - 1){
                return true;
            }
        }
        return false;
    }

这个题目,如果你想到采用覆盖范围这个想法,我想解决不是难事,这里就是转换一下。

最短跳跃游戏

参考题目地址:45. 跳跃游戏 II - 力扣(LeetCode)


这是上一道题目的进阶版,假设一定到达末尾,求最短步数。就拿上图的3种走法,我们怎么选出最短的那个呢?

这里采用骨头哥的:贪婪+双指针

在上一题的基础上做改进,这里准备4个变量。

  1. left用来一步步遍历数组
  2. steps用来记录到达当前位置的最少步数
  3. right表示当前步数下能够覆盖到的最大范围
  4. 我们还需要一个临时变量cover,假如left到达right时才更新right。

此时还么有达到终点,我们需要继续走,这是可以选择的元素是{2,4},如果选择2,则可以到达left+num[left]=3 + 2 = 5,如果选择4,则是left+num[left]=4 +8= 8,此时以已经过界了,一定可以覆盖到结尾的。

然后用left和right将step的范围标记一下:

此时还么有达到终点,我们需要继续走,这是可以选择的元素是{2,4},如果选择2,则可以到达left+num[left]=3 + 2 = 5,如果选择4,则是left+num[left]=4 +8= 8,此时以已经过界了,一定可以覆盖到结尾的。

也就是说,最后一定可以到达,至少需要走3步的。

看了这么多,代码要怎么写呢?

java 复制代码
    /**
     * 跳跃游戏进阶
     * @param nums
     * @return
     */
    public static int jump(int[] nums) {
      int step = 0;
      int maxPosition = 0;
      int right = 0;
      for(int left = 0; left < nums.length ; left++) {
          // 覆盖的最远距离
          maxPosition = Math.max(maxPosition, nums[left] + left);
          // 遇到边界,更新边界
          if (left == right){
              right = maxPosition;
              step++;
          }
          // 当然如果越界了,直接返回+1
          if (right >= nums.length - 1){
              return step;
          }
      }
      return step;
    }

总结

提示:贪婪算法;跳跃游戏;进阶游戏;跳跃问题;跳跃游戏进阶


如果有帮助到你,请给题解点个赞和收藏,让更多的人看到 ~ ("▔□▔)/

如有不理解的地方,欢迎你在评论区给我留言,我都会逐一回复 ~

也欢迎你 关注我 ,喜欢交朋友,喜欢一起探讨问题。

相关推荐
Swift社区42 分钟前
从 JDK 1.8 切换到 JDK 21 时遇到 NoProviderFoundException 该如何解决?
java·开发语言
DKPT2 小时前
JVM中如何调优新生代和老生代?
java·jvm·笔记·学习·spring
phltxy2 小时前
JVM——Java虚拟机学习
java·jvm·学习
seabirdssss3 小时前
使用Spring Boot DevTools快速重启功能
java·spring boot·后端
喂完待续3 小时前
【序列晋升】29 Spring Cloud Task 微服务架构下的轻量级任务调度框架
java·spring·spring cloud·云原生·架构·big data·序列晋升
benben0443 小时前
ReAct模式解读
java·ai
轮到我狗叫了4 小时前
牛客.小红的子串牛客.kotori和抽卡牛客.循环汉诺塔牛客.ruby和薯条
java·开发语言·算法
Volunteer Technology5 小时前
三高项目-缓存设计
java·spring·缓存·高并发·高可用·高数据量
栗子~~5 小时前
bat脚本- 将jar 包批量安装到 Maven 本地仓库
java·maven·jar