LeetCode 841:钥匙和房间 Keys and Rooms

题目:

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

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

最初,除 0 号房间外的其他全部房间都被锁住。数组

你能够自由地在房间之间来回走动。bash

若是能进入每一个房间返回 true,不然返回 false函数

​ There are N rooms and you start in room 0. Each room has a distinct number in 0, 1, 2, ..., N-1, and each room may have some keys to access the next room.spa

​ Formally, each room i has a list of keys rooms[i], and each key rooms[i][j] is an integer in [0, 1, ..., N-1] where N = rooms.length. A key rooms[i][j] = v opens the room with number v.3d

Initially, all the rooms start locked (except for room 0).code

You can walk back and forth between rooms freely.orm

Return true if and only if you can enter every room.cdn

示例 1:

输入: [[1],[2],[3],[]]
输出: true
解释:  
咱们从 0 号房间开始,拿到钥匙 1。
以后咱们去 1 号房间,拿到钥匙 2。
而后咱们去 2 号房间,拿到钥匙 3。
最后咱们去了 3 号房间。
因为咱们可以进入每一个房间,咱们返回 true复制代码

示例 2:

输入:[[1,3],[3,0,1],[2],[0]]
输出:false
解释:咱们不能进入 2 号房间。
复制代码

提示:

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

Note:

  1. 1 <= rooms.length <= 1000
  2. 0 <= rooms[i].length <= 1000
  3. The number of keys in all rooms combined is at most 3000.

解题思路:

​ 很简单的一道题,从0号房间开始递归遍历就能够了。惟一须要注意的是如何判断房间是否访问过。能够用set哈希表把已访问过的房间号记录下来,最后若是哈希表长度和rooms长度相等,那么就意味着全部房间都可到达。

代码:

Set集合(Java):

class Solution {
    Set<Integer> set = new LinkedHashSet<>();

    public boolean canVisitAllRooms(List<List<Integer>> rooms) {
        helper(rooms, 0);
        return set.size() == rooms.size();//长度相等则能够到达全部房间
    }

    private void helper(List<List<Integer>> rooms, int index) {
        if (set.contains(index)) return;
         set.add(index);//已访问房间号加入哈希表
        for (Integer i : rooms.get(index)) {//遍历房间的每个钥匙
                helper(rooms, i);//进入递归
        }
    }
}
复制代码

​ 能够看到用哈希表解题方法在递归期间会多出许多set函数的调用,如 set.add() 、set.contains(),相对不少这道题解题时间,这个开销是很大。对这道题而言,是彻底能够用数组避免的。

Java:

class Solution {

    public boolean canVisitAllRooms(List<List<Integer>> rooms) {
        int len = rooms.size();
        int[] visited = new int[len];//初始化等长数组,数组每一个值默认为0
        helper(rooms, 0, visited);
        for (int i : visited)
            if (i == 0) return false;//数组中依然有0,则证实有房间未访问到
        return true;
    }

    private void helper(List<List<Integer>> rooms, int index, int[] visited) {
        if (visited[index] == 1) return;//若是该房间已访问过,直接返回
        visited[index] = 1;//在访问过的房间,改成1来标记
        for (Integer i : rooms.get(index)) {//遍历
            helper(rooms, i, visited);
        }
    }
}
复制代码

Python:

class Solution:
    def canVisitAllRooms(self, rooms: List[List[int]]) -> bool:
        size=len(rooms)
        self.visited = [False]*size # 初始化等长数组,默认为False,全部房间均未访问
        self.helper(rooms, 0)
        return all(self.visited)

    def helper(self, rooms: List[List[int]], index: int) -> None:
        if self.visited[index]:#若是为True,该房间已访问过,直接返回
            return
        self.visited[index] = True #在访问的房间标记为True
        for i in rooms[index]:#遍历钥匙
            self.helper(rooms, i)#进入递归函数
复制代码

欢迎关注微.信公.众号:爱写Bug

在这里插入图片描述
相关文章
相关标签/搜索