LeetCode-55-跳跃游戏
in LeetCode with 0 comment

LeetCode-55-跳跃游戏

in LeetCode with 0 comment

原题地址:跳跃游戏

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

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

判断你是否能够到达最后一个位置。

示例 1:

输入: [2,3,1,1,4]
输出: true
解释: 从位置 0 到 1 跳 1 步, 然后跳 3 步到达最后一个位置。

示例 2:

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

动态规划

跳跃游戏II 为同一思路。

利用一个数组存储每个位置是否能到达终点,从后往前扫描,如果当前位置一步能跳到的位置有一个可以到达终点,则该位置可以到终点,否则不可到达。

具体的实现代码如下:

/**
 * @param {number[]} nums
 * @return {boolean}
 */
const canJump1 = function(nums) {
    let dp = new Array(nums.length).fill(false);
    dp[nums.length - 1] = true;
    for (let i = nums.length - 2; i >= 0; i --) {
        // 如果当前位置比后一位置能多跳一步,则这多的一步刚好能到达后一位置
        // 他们的可达范围一定是相同的
        if (nums[i] === nums[i + 1] + 1) {
            dp[i] = dp[i + 1];
            continue;
        }
        // 尝试每一种可能的步数,任意一个能到达,则该位置是可以到达终点的
        // 由于dp数组的默认值为false,所以全部尝试失败的情况不用处理
        // 最大跳跃长度为0的位置,则进不了循环,所以也是正确的
        for (let j = 1; j <= nums[i]; j ++) {
            if (dp[i + j]) {
                dp[i] = true;
                break;
            }
        }
    }
    return dp[0];
};

测试:

let start = new Date();
const test = canJump1;
console.log(test([2,3,1,1,4])); // true
console.log(test([3,2,1,0,4])); // false
console.log(new Date().getTime() - start.getTime()); // 9

时间复杂度: 双重遍历,时间复杂度为$O(N^2)$
空间复杂度: $dp$数组长度为N,空间复杂度为$O(N)$