Keys and Rooms
There are n rooms numbered 0 to n - 1. Every room is locked except room 0, and each room holds a list of keys that open other rooms. Starting in room 0, return true if you can visit every room , and false otherwise. Keep a stack of rooms you have opened but not yet searched. Take one off the stack, pick up its keys, open any room those keys unlock for the first time, and push those rooms on. When the stack runs dry, count how many rooms you opened.
Constraints
- n === rooms.length, 2 ≤ n ≤ 1000
- 0 ≤ roomsi.length ≤ 1000
- Every key is a valid room number
- A room may hold a key to itself or a duplicate key
Example
rooms = [[1], [2], [3], []]trueExplanation Room 0 holds the key to room 1, room 1 holds the key to room 2, and room 2 holds the key to room 3. All four rooms get opened.
In plain terms
- Stack
- A pile where you always take the item you put down most recently. Pushing adds to the top, popping removes from the top.
- Depth-first search
- A way of exploring a graph where you follow one path as far as it goes before backing up and trying another. A stack gives you this for free.
- Visited
- A record of which rooms you have already opened, so you never open the same room twice and never loop forever.
- Reachable
- A room you can get to by following keys from room 0. Rooms that are not reachable are the reason the answer can be false.
One cell per room, value = open or shut
You start inside room 0, so it is open and the other three are still shut.
What happens in this step
rooms = [[1], [2], [3], []] stack = [0] opened = 1 Room 0 is marked open straight away. Rooms 1, 2 and 3 are shut until a key turns up.
Steps to visualize
- The row has one cell per room. The label is the room number and the value says whether it is open yet.
- Room 0 starts open because you begin inside it. Everything else starts shut.
- Take a room off the stack and read the keys lying in it.
- Any key that opens a still-shut room flips that room to open and pushes it on the stack.
- When the stack is empty, compare the number of open rooms with the total number of rooms.
Walk through the code
Same walkthrough, now with the code. Press Next to move one step and watch which lines run.
You start inside room 0, so it is open and the other three are still shut.
What happens in this step
rooms = [[1], [2], [3], []] stack = [0] opened = 1 Room 0 is marked open straight away. Rooms 1, 2 and 3 are shut until a key turns up.
Solution
function canVisitAllRooms(rooms) {
const visited = new Array(rooms.length).fill(false);
const stack = [0];
visited[0] = true;
let opened = 1;
while (stack.length > 0) {
const room = stack.pop();
for (const key of rooms[room]) {
if (!visited[key]) {
visited[key] = true;
opened += 1;
stack.push(key);
}
}
}
return opened === rooms.length;
}- Time
- O(n + k), where k is the total number of keys
- Space
- O(n)
Test cases
| Input | Expected | Covers |
|---|---|---|
rooms = [[1], [2], [3], []] | true | example from the docstring |
rooms = [[1, 3], [3, 0, 1], [2], [0]] | false | one room holds the only key to itself and stays locked |
rooms = [[1], []] | true | smallest input, two rooms joined by one key |
rooms = [[2], [], [1]] | true | rooms are opened in an order that skips ahead and comes back |
rooms = [[1], [], [3], []] | false | a separate pair of rooms nothing points at |
rooms = [[0, 1, 1], [0, 2], [0]] | true | repeated keys and keys to already open rooms |