sl1673495 / leetcode-javascript

:beers: 喝杯小酒,一起做题。前端攻城狮从零入门算法的宝藏题库,根据知名算法老师的经验总结了 100+ 道 LeetCode 力扣的经典题型 JavaScript 题解和思路。已按题目类型分 label,一起加油。

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

跳跃游戏 III-1306

sl1673495 opened this issue · comments

commented

这里有一个非负整数数组  arr,你最开始位于该数组的起始下标  start  处。当你位于下标  i  处时,你可以跳到  i + arr[i] 或者 i - arr[i]。

请你判断自己是否能够跳到对应元素值为 0 的 任一 下标处。

注意,不管是什么情况下,你都无法跳到数组之外。

示例 1:

输入:arr = [4,2,3,0,3,1,2], start = 5
输出:true
解释:
到达值为 0 的下标 3 有以下可能方案:
下标 5 -> 下标 4 -> 下标 1 -> 下标 3
下标 5 -> 下标 6 -> 下标 4 -> 下标 1 -> 下标 3
示例 2:

输入:arr = [4,2,3,0,3,1,2], start = 0
输出:true
解释:
到达值为 0 的下标 3 有以下可能方案:
下标 0 -> 下标 4 -> 下标 1 -> 下标 3
示例 3:

输入:arr = [3,0,2,1,2], start = 2
输出:false
解释:无法到达值为 0 的下标 1 处。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/jump-game-iii
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

思路

利用 BFS 的思路,维护一个队列 queue 表示待处理的下标,先把 start 起点放入队列中,然后从起点开始根据起点对应的值分别把左右两边对应的下标放入队列中,不断循环。形象点来说就是每次跳完一格,都把这格对应的左右两边可跳的下标放入队列里,下次继续跳。

  1. 当左下标小于 0 或者右下标超出数组长度时,就不用放入队列了。
  2. 每次处理完当前的格子后,要用 visited 数组记录下来,下次对于这个处理过的下标就不再放入队列中。

如果这个过程中发现了某一格是 0,那么就成功,如果整个循环结束了都没发现,那么就失败。

/**
 * @param {number[]} arr
 * @param {number} start
 * @return {boolean}
 */
let canReach = function (arr, start) {
  let n = arr.length;
  let visited = [];
  let queue = [start];
  while (queue.length) {
    let index = queue.pop();
    let val = arr[index];
    if (val === 0) {
      return true;
    }
    let left = index - val;
    let right = index + val;
    if (left >= 0 && !visited[left]) {
      queue.push(left);
    }
    if (right < n && !visited[right]) {
      queue.push(right);
    }
    visited[index] = true;
  }
  return false;
};