本文已参与「新人创作礼」活动,一起开启掘金创作之路。
题目
给你一个非负整数数组 nums ,你最初位于数组的第一个位置。
数组中的每个元素代表你在该位置可以跳跃的最大长度。
你的目标是使用最少的跳跃次数到达数组的最后一个位置。
假设你总是可以到达数组的最后一个位置。
输入: nums = [2,3,1,1,4]
输出: 2
解释: 跳到最后一个位置的最小跳跃数是 2。
从下标为 0 跳到下标为 1 的位置,跳 1 步,然后跳 3 步到达数组的最后一个位置。
题目解析
思路一
我们可以记录每走一步所能到达的最远位置,作为下一步的终点,起点为当前位置的下一位置,起点到终点为下一步的起始位置,获取下一步能达到的最远位置,以此类推,直到当前步骤最远位置可达终点
var jump = function(nums) {
let start = 0, // 第 n 轮起点
end = 0, // 第 n 轮终点,len+1 可作为 n+1 轮的起点
maxPos = 0, // 第 n 轮所能到达的最远位置,可作为 n+1 轮的终点
ans = 0 // 记录当前是第几轮,为已走步数
while(end < nums.length-1) {
// 从起点到终点,计算当前轮下一步能达到的最远位置
for(let i=start; i<= end; i++) {
maxPos = maxPos > i+nums[i] ? maxPos : i+nums[i]
}
// 下一轮起点为当前轮+1
start = end + 1
// 下一轮为当前轮所能达到的最远位置
end = maxPos
// 步数计算
ans ++
}
return ans
};
思路二
/**
* @param {number[]} nums
* @return {number}
*/
var jump = function(nums) {
if(nums.length <=1) return 0
//将一开始所在的第一步添加进去
let res = [nums[0]]
let lastStepIndex = 0
while(res[res.length-1] < nums.length-1-lastStepIndex){
// 上一步能走的总步数
let steps = res[res.length-1]
// 预备节点:下一步能走的最远的位置,至少要大于上一步能走的步数
let newMaxStepIndex = lastStepIndex
for(let i= 1;i<=steps;i++){
// 这里的i为:从上一个记录点到现在所走的步数
// 当前这一步的Index
let curIndex = i + lastStepIndex
// 当前这一步能走的步数
let curSteps = nums[curIndex]
/*
i+curSteps :从上一个记录点到现在已经走了的步数 + 当前节点能走的步数
nums[newMaxStepIndex] + (newMaxStepIndex - lastStepIndex):预备记录点能走的步数 + 上一个记录点至预备节点之间的步数,注意这里并不是拿已经走了的步数i去加预备节点的步数,因为当前的i已经超过了预备节点所在的位置
*/
if(i+curSteps > nums[newMaxStepIndex] + (newMaxStepIndex - lastStepIndex)){
newMaxStepIndex = curIndex
}
}
res.push(nums[newMaxStepIndex])
lastStepIndex = newMaxStepIndex
}
return res.length
};