[LeetCode] 841. Keys and Rooms 鑰匙與房間

 

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. html

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.git

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

You can walk back and forth between rooms freely.函數

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

Example 1:url

Input: [[1],[2],[3],[]]
Output: true
Explanation:  
We start in room 0, and pick up key 1.
We then go to room 1, and pick up key 2.
We then go to room 2, and pick up key 3.
We then go to room 3.  Since we were able to go to every room, we return true.

Example 2:spa

Input: [[1,3],[3,0,1],[2],[0]]
Output: false
Explanation: We can't enter the room with number 2.

Note:code

  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,問最終是否能夠打開全部的房間。這不禁得讓博主想起了驚悚片《萬能鑰匙》,還真是頭皮發麻啊。趕忙扯回來,這是一道典型的有向圖的遍歷的題,鄰接鏈表都已經創建好了,這裏直接遍歷就行了,這裏先用 BFS 來遍歷。使用一個 HashSet 來記錄訪問過的房間,先把0放進去,而後使用 queue 來輔助遍歷,一樣將0放入。以後進行典型的 BFS 遍歷,取出隊首的房間,而後遍歷其中的全部鑰匙,若該鑰匙對應的房間已經遍歷過了,直接跳過,不然就將鑰匙加入 HashSet。此時看若 HashSet 中的鑰匙數已經等於房間總數了,直接返回 true,由於這表示全部房間已經訪問過了,不然就將鑰匙加入隊列繼續遍歷。最後遍歷結束後,就看 HashSet 中的鑰匙數是否和房間總數相等便可,參見代碼以下:orm

 

解法一:htm

class Solution {
public:
    bool canVisitAllRooms(vector<vector<int>>& rooms) {
        unordered_set<int> visited{{0}};
        queue<int> q{{0}};
        while (!q.empty()) {
            int t = q.front(); q.pop();
            for (int key : rooms[t]) {
                if (visited.count(key)) continue;
                visited.insert(key);
                if (visited.size() == rooms.size()) return true;
                q.push(key);
            }
        }
        return visited.size() == rooms.size();
    }
};

 

咱們也可使用遞歸的解法來作,仍是使用 HashSet 來記錄訪問過的房間,遞歸函數還須要傳進當前的房間,還有 HashSet,首先將當前房間加入 HashSet,而後遍歷此房間中的全部鑰匙,若是其對應的房間沒有訪問過,則調用遞歸函數,參見代碼以下:

 

解法二:

class Solution {
public:
    bool canVisitAllRooms(vector<vector<int>>& rooms) {
        unordered_set<int> visited;
        helper(rooms, 0, visited);
        return visited.size() == rooms.size();
    }
    void helper(vector<vector<int>>& rooms, int cur, unordered_set<int>& visited) {
        visited.insert(cur);
        for (int key : rooms[cur]) {
            if (!visited.count(key)) helper(rooms, key, visited);
        }
    }
};

 

Github 同步地址:

https://github.com/grandyang/leetcode/issues/841

 

參考資料:

https://leetcode.com/problems/keys-and-rooms/

https://leetcode.com/problems/keys-and-rooms/discuss/133944/Java-8-lines

https://leetcode.com/problems/keys-and-rooms/discuss/133855/Straight-Forward

 

LeetCode All in One 題目講解彙總(持續更新中...)

相關文章
相關標籤/搜索