Offer 驾到,掘友接招!我正在参与2022春招打卡活动,点击查看活动详情。
题目描述
给你一个非负整数数组 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 <= 1040 <= nums[i] <= 1000
题解
通过这道题,可以明显看到 贪心 算法的双指针应用。
有两个重点需要注意:
-
先进行右指针的跳跃,此时需要count++
-
只有左右两个指针相等的时候,才可以进入下一个跳跃阶段
此时我们会找到当前能够跳的最远位置,就是下一次 right 指针所在的位置。
贪心
const jump = (nums) => {
const numsLength = nums.length
let left = 0
let count = 0
let temporary = 0 // 临时存储的当前最大值
if (numsLength === 1) return count
// 先让右指针跳
let right = left + nums[left]
count++
// 判断 右指针 是否未超出
while (right < numsLength - 1) {
// 获取右指针 和 右指针下标所在值 的和,即为目前下一次能够到达的值
const rightVal = right + nums[right]
// 如果左指针小于右指针
if (left < right) {
const leftVal = left + nums[left]
// 如果 左指针能跳的最大值 大于 右指针能跳的最大值
if (leftVal > rightVal) {
// 保存能够跳的最大值
// 这里保存就是为了查看后面是否还有更大的值
temporary = leftVal > temporary ? leftVal : temporary
}
}
// 如果左指针与右指针重合,代表可以进入下一个跳跃阶段
if (left === right) {
// temporary 是否被赋值,如果被赋值,将采用最大的那个作为跳板.
right = rightVal < temporary ? temporary : rightVal
count++
}
// 每次执行++操作
left++
}
return count
}
总结
该题目 31 :双指针算法的应用,并在局部中找到最优解,就是 贪心 。