841. Keys and Rooms
Description
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.
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
.
Initially, all the rooms start locked (except for room 0
).
You can walk back and forth between rooms freely.
Return true
if and only if you can enter every room.
Example 1:
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:
Input: [[1,3],[3,0,1],[2],[0]]
Output: false
Explanation: We can't enter the room with number 2.
Note:
1 <= rooms.length <= 1000
0 <= rooms[i].length <= 1000
- The number of keys in all rooms combined is at most
3000
.
Solution
一开始想的复杂了,首先这是一个有向图,本来以为0和1之间是双向关系才能来回走。但后来发现题目中"You can walk back and forth between rooms freely."的意思是单向关系就可以来回走。。所以实际上可以看作是一张无向图。那么从节点0开始,使用DFS或者BFS探索即可。
DFS, O(n + keys), S(n)
class Solution {
public boolean canVisitAllRooms(List<List<Integer>> rooms) {
Set<Integer> visited = new HashSet<>();
dfs(rooms, 0, visited);
return visited.size() == rooms.size();
}
private void dfs(List<List<Integer>> rooms, int curr, Set<Integer> visited) {
if (!visited.add(curr)) {
return;
}
for (int next : rooms.get(curr)) {
dfs(rooms, next, visited);
}
}
}
BFS, O(n + keys), S(w)
class Solution {
public boolean canVisitAllRooms(List<List<Integer>> rooms) {
Set<Integer> visited = new HashSet<>();
Queue<Integer> queue = new LinkedList<>();
queue.offer(0);
visited.add(0);
while (!queue.isEmpty()) {
int curr = queue.poll();
for (int next : rooms.get(curr)) {
if (visited.add(next)) {
queue.offer(next);
}
}
}
return visited.size() == rooms.size();
}
}