一天一大 lee(钥匙和房间)难度:中等-Day20200831

时间:2022-07-25
本文章向大家介绍一天一大 lee(钥匙和房间)难度:中等-Day20200831,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
题目:[1]

有 N 个房间,开始时你位于 0 号房间。每个房间有不同的号码:0,1,2,...,N-1,并且房间里可能有一些钥匙能使你进入下一个房间。

在形式上,对于每个房间 i 都有一个钥匙列表 rooms[i],每个钥匙 rooms[i][j] 由 [0,1,...,N-1] 中的一个整数表示,其中 N = rooms.length。钥匙 rooms[i][j] = v 可以打开编号为 v 的房间。

最初,除 0 号房间外的其余所有房间都被锁住。

你可以自由地在房间之间来回走动。

如果能进入每个房间返回 true,否则返回 false

示例

  1. 示例 1
输入: [[1],[2],[3],[]]
输出: true
解释:
我们从 0 号房间开始,拿到钥匙 1。
之后我们去 1 号房间,拿到钥匙 2。
然后我们去 2 号房间,拿到钥匙 3。
最后我们去了 3 号房间。
由于我们能够进入每个房间,我们返回 true。
  1. 示例 2
输入:[[1,3],[3,0,1],[2],[0]]
输出:false
解释:我们不能进入 2 号房间。

提示

  1. 1<= rooms.length <= 1000
  2. 0 <= rooms[i].length <= 1000
  3. 所有房间中的钥匙数量总计不超过 3000

抛砖引玉

抛砖引玉

思路

使用递归逐个开启房间,(递归开房

  • 开启的房间从 rooms 中清除索引
  • 最终遍历 rooms,有剩余未开启的房间就返回 false,否则返回 true

递归

  • 参数:房间索引
  • 终止条件:索引边界
/**
 * @param {number[][]} rooms
 * @return {boolean}
 */
var canVisitAllRooms = function (rooms) {
  function openIndex(index) {
    let i = index
    while (rooms[i].length) {
      // 开启则清除索引
      let item = rooms[i].shift()
      openIndex(item)
    }
  }
  // 从第一个房间开启
  openIndex(0)
  let i = 0
  while (i < rooms.length) {
    if (rooms[i].length === 0) {
      i++
    } else {
      // 有房间未开启直接返回false
      return false
    }
  }
  return true
}

深度优先搜索

使用 map 的哈希记录已经开启的房间,开启过不用再次开启,避免上面方法中的重复开启的逻辑。

最后,开启的房间数等于 rooms 的长度就说明都开启了,否则返回 false

/**
 * @param {number[][]} rooms
 * @return {boolean}
 */
var canVisitAllRooms = function (rooms) {
  let len = rooms.length,
    map = new Map()
  dfs(rooms, 0)

  function dfs(rooms, x) {
    map.set(x, true)
    for (let i = 0; i < rooms[x].length; i++) {
      if (!map.has(rooms[x][i])) {
        dfs(rooms, rooms[x][i])
      }
    }
  }

  return map.size == len
}

广度优先搜索

/**
 * @param {number[][]} rooms
 * @return {boolean}
 */
var canVisitAllRooms = function (rooms) {
  let len = rooms.length,
    map = new Map(),
    queue = [0]
  map.set(0, true)

  while (queue.length) {
    let x = queue.shift()
    for (let i = 0; i < rooms[x].length; i++) {
      if (!map.has(rooms[x][i])) {
        queue.push(rooms[x][i])
        map.set(rooms[x][i], true)
      }
    }
  }

  return map.size == len
}