【LeetCode】每日一题 跳跃游戏 II

55 阅读2分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第20天,点击查看活动详情

45. 跳跃游戏 II

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

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

你的目标是使用最少的跳跃次数到达数组的最后一个位置。

假设你总是可以到达数组的最后一个位置。

「示例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

解题思路

// 第一种
在抵达当前区间最大跳跃长度之前,用maxDistance记录可跳跃的最大长度;
当当前位置为上一个算出最大长度可抵达endOfCanReach的位置时,则步数+1,更新endOfCanReach = maxDistance
判断endOfCanReach >= 数组长度-1(默认在第一个位置了),则说明已经得到最短的步数了,break退出循环
返回step
​
// 第二种
贪心算法
从初始位置开始,找到当前位置能跳到的最远位置,在在最远位置与当前位置范围之内,继续查找能跳到的最远位置。

代码实现

// 第一种
var jump = function(nums) {
    let maxDistance = 0, // 存储最大长度
        endOfCanReach = 0, // 存储当前要抵达的位置
        steps = 0; // 存储步数
    const len = nums.length; // 数组长度
    for(let i = 0; i < len; i++){
        if (endOfCanReach >= len - 1){ // 当要抵达的位置大于等于数组长度-1,则已经获取到最小的步数了,break退出循环
            break;
        }
        maxDistance = Math.max(maxDistance, i + nums[i]) // 判断获取最大的长度
        if (i === endOfCanReach){ // 当当前位置为要抵达的位置时,更新抵达位置,step++
            endOfCanReach = maxDistance;
            steps++;
        }
    }
    return steps;
};
​
// 第二种
var jump = function(nums) {
    let end = 0,
        longest = 0,
        count = 0;
    for (let i = 0; i < nums.length-1; i++) {
    // 注意此处设定为i<length-1
    // 根据题目要求,假定每一个组合都能够跳到最终位置,因此最后一个位置不需要计算在内
        longest = Math.max(longest, nums[i] + i);
        if (end === i) {
            count++;
            end = longest;
        }
    }
    return count;
};

如果你对这道题目还有疑问的话,可以在评论区进行留言;

\