面试经典算法150题系列-跳跃游戏

跳跃游戏:

给你一个非负整数数组 nums ,你最初位于数组的 第一个下标 。数组中的每个元素代表你在该位置可以跳跃的最大长度。

判断你是否能够到达最后一个下标,如果可以,返回 true ;否则,返回 false 。

示例 1:

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

示例 2:

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

实现思路:

这个问题是一个经典的贪心算法问题,通常被称为“跳跃游戏”。要解决这个问题,你可以从左到右遍历数组,使用一个变量来跟踪当前可以到达的最远位置。在每一步中,更新这个最远位置,如果当前位置超过了之前记录的最远位置,说明无法到达数组的末尾。
以下是解决这个问题的算法步骤:
1.初始化两个变量,maxReach 表示当前可以到达的最远下标,初始值为 0,因为最开始你位于第一个下标。初始化另一个指针 i 表示当前考虑的下标,初始值也为 0。

2.遍历数组 nums 从第一个元素开始(下标为 0):
(1)如果 i 小于或等于 maxReach,说明当前下标仍然在可到达范围内。
     更新 maxReach 为 max(maxReach, i + nums[i]),即当前最远位置与当前下标加上可以跳跃的最大长度中的较大值。
(2)如果 maxRearch 能够到达或超过数组的最后一个下标(nums.length - 1),则返回 true,否则在循环结束后返回 false。

思路模拟:假设我们有数组 nums = [2, 3, 1, 1, 4],我们可以这样一步步执行算法:

  1. 初始状态:最远可达到下标maxReach = 0,当前下标 = 0
  2. 考虑第一个元素 nums[0] = 2
    • 因为 0 ≤ maxReach,更新 maxReach = max(00 + 2) = 2
    • 此时,maxReach 为 2,意味着我们可以至少到达下标 2 的位置
  3. 移动到下标 1:
    • 因为 1 ≤ maxReach,更新 maxReach = max(21 + 3) = 4
    • 此时,maxReach 为 4,意味着我们可以至少到达下标 4 的位置
  4. 考虑下标 2:
    • 因为 2 ≤ maxReach,更新 maxReach = max(42 + 1) = 4(不变)
  5. 考虑下标 3:
    • 因为 3 ≤ maxReach,更新 maxReach = max(43 + 1) = 4(不变)
  6. 此时,我们已经考虑了所有元素,maxReach 能够达到最后一个下标(4),因此返回 true。

大家可以按照这样的方式去模拟第二组示例,你可以发现maxReach最多到达下标3,无法到达最后一个下标4。

实现代码:

public boolean canJump(int[] nums) {
    int maxReach = 0; // 当前可以到达的最远下标

    for (int i = 0; i < nums.length; i++) {
        if (i <= maxReach) { // 如果当前下标在可到达范围内
            maxReach = Math.max(maxReach, i + nums[i]); // 更新最远下标
        }
    }

    return maxReach >= nums.length - 1; // 如果最远下标能够到达或超过最后一个下标,返回 true
}

这题用到了贪心算法,有兴趣的朋友可以看看买卖股票最佳时机||,此题也是我提供了两个思路,第二个思路也用到了贪心算法,还对其思想、特点、使用场景做了补充。贪心算法是比较常见的算法了,我们只能多写题,去感悟它的独特之处。

  • 15
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值