LC-45. 跳跃游戏 II

137 阅读1分钟

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 <= 104
  • 0 <= 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 :双指针算法的应用,并在局部中找到最优解,就是 贪心 。