有 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 <= rooms.length <= 1000
0 <= rooms[i].length <= 1000
3000
。Note:
1 <= rooms.length <= 1000
0 <= rooms[i].length <= 1000
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