力扣【动态规划专题】55. 跳跃游戏

126 阅读1分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第 13 天,点击查看活动详情

题目链接

55. 跳跃游戏 - 力扣(LeetCode)

题目描述

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

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

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

测试用例

用例1:

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

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

限制

  • 1 <= nums.length <= 3 * 10^4
  • 0 <= nums[i] <= 10^5

题目分析

阅读题目,获取到几个关键信息:

  1. 有一个非空数组,我们初始位置为数组下标 0
  2. 数组上对应下标 x 的值表示,我们最远可以到下标为 max = x+nums[x] 的位置
  3. 基于上一点,在下标区间 [x, max] 中,如果其中有一个下标 y,存在 y+nums[y]>max,那么我们需要重置 max 的值
  4. 不断重复上几步,当我们算出来的 max>=nums.length 的时候,表示我们能够到达数组的最后一个下标,可以返回 true
  5. 如果存在一种情况, max 下标的值为 0,且 [x, max] 区间内计算的最大值,都无法超过 max, 这种情况下无法向后推进,只能返回 false

代码实现

完整的代码实现如下

var canJump = function (nums) {
    let flag = false;
    let max = nums[0] + 0;
    for (let i = 0; i <= max; max = Math.max(max, nums[i] + i), i++) {
        if (nums[i] + i + 1 >= nums.length) {
            flag = true;
            break;
        }
        if (nums[i] == 0 && max == nums[i] + i) {
            break;
        }
    }
    if (nums.length == 1) return true; 
    return flag;
};

通过不断的试错,终于打补丁过了😂

image.png