Bird
Raised Fist0
Interview Prepgraphs-dfs-bfsmediumAmazonGoogleFacebook

Keys and Rooms

Choose your preparation mode4 modes available
▶
Steps
setup

Initialize variables

Initialize the number of rooms (n), the visited array to track visited rooms, and the count of visited rooms set to zero.

💡 Setting up these variables is essential to track progress and avoid revisiting rooms.
Line:n = len(rooms) visited = [False] * n count = 0
💡 We now have a clean slate to start DFS and track which rooms get visited.
📊
Keys and Rooms - Watch the Algorithm Execute, Step by Step
Watching the algorithm step through each room and key reveals how DFS explores the graph and why early stopping is possible once all rooms are visited.
Step 1/11
·Active fill★Answer cell
Visiting: none
0
1
2
3
Visiting: 0
0
1
2
3
Queue / Stack
0
Visiting: 0
Edge: 0 → 1
0
1
2
3
Queue / Stack
0
Visiting: 1
0
1
2
3
Queue / Stack
01
Visiting: 1
Edge: 1 → 2
0
1
2
3
Queue / Stack
01
Visiting: 2
0
1
2
3
Queue / Stack
012
Visiting: 2
Edge: 2 → 3
0
1
2
3
Queue / Stack
012
Visiting: 3
0
1
2
3
Queue / Stack
0123
Visiting: 3
0
1
2
3
Queue / Stack
0123
Visiting: none
0
1
2
3
Visiting: none
0
1
2
3

Key Takeaways

✓ DFS explores rooms by following keys, marking rooms visited to avoid cycles.

Reading code alone can hide how DFS uses recursion to explore connected rooms; visualization shows the call stack and visited states clearly.

✓ Early exit when all rooms are visited saves unnecessary exploration.

The early stopping condition is subtle in code but critical for efficiency; seeing it in action clarifies its impact.

✓ Edges used in DFS form a tree showing the path of exploration.

Visualizing tree edges helps understand the traversal order and how keys unlock new rooms step-by-step.

Practice

(1/5)
1. Consider the following BFS-based cloneGraph function. Given the input graph with nodes 1 connected to 2 and 3, and node 2 connected to 3, what is the value of the neighbors list of the cloned node corresponding to node 1 after the first iteration of the while loop (i.e., after processing node 1)?
easy
A. A list containing cloned nodes with values [2, 3]
B. An empty list []
C. A list containing cloned nodes with values [1]
D. A list containing cloned nodes with values [3, 2]

Solution

  1. Step 1: Trace the first iteration of the while loop

    Initially, queue contains node 1. We pop node 1 and iterate over its neighbors: nodes 2 and 3.
  2. Step 2: Update visited and neighbors

    Nodes 2 and 3 are not visited, so they are cloned and added to visited and queue. Then, the cloned node 1's neighbors list is appended with cloned nodes 2 and 3 in order.
  3. Final Answer:

    Option A -> Option A
  4. Quick Check:

    Neighbors of cloned node 1 after first iteration are clones of nodes 2 and 3 [OK]
Hint: Neighbors appended in order during BFS iteration [OK]
Common Mistakes:
  • Assuming neighbors list is empty after first iteration
  • Mixing up order of neighbors appended
2. Consider the following Python code implementing Kahn's Algorithm for course scheduling. What is the return value of canFinish(3, [[1,0],[2,1]]) after the while loop completes?
easy
A. false
B. true
C. Raises an error due to empty queue
D. Returns true only if numCourses is 2

Solution

  1. Step 1: Initialize graph and in-degree arrays

    Graph: 0 -> [1], 1 -> [2], 2 -> []. In-degree: [0,1,1]. Queue starts with nodes having in-degree 0 -> [0].
  2. Step 2: Process queue and update count

    Pop 0, count=1; decrement in-degree of 1 to 0, enqueue 1. Pop 1, count=2; decrement in-degree of 2 to 0, enqueue 2. Pop 2, count=3; queue empty.
  3. Final Answer:

    Option B -> Option B
  4. Quick Check:

    All courses processed, so return true [OK]
Hint: Count equals numCourses means no cycle [OK]
Common Mistakes:
  • Off-by-one error in count increment
  • Misunderstanding queue initialization
  • Confusing in-degree decrement timing
3. You are given a grid of heights and need to find a path from the top-left to the bottom-right cell such that the maximum absolute difference in heights between adjacent cells on the path is minimized. Which algorithmic approach guarantees finding the optimal solution efficiently?
easy
A. Dijkstra's algorithm variant treating edge weights as the maximum effort along the path
B. Greedy algorithm that always moves to the adjacent cell with the smallest height difference
C. Dynamic programming that sums all height differences along paths
D. Depth-first search with backtracking exploring all paths exhaustively

Solution

  1. Step 1: Understand the problem's cost metric

    The cost to minimize is the maximum edge effort along the path, not the sum of efforts.
  2. Step 2: Identify suitable algorithm

    Dijkstra's algorithm can be adapted to track the maximum edge cost on paths, guaranteeing the minimal maximum effort path.
  3. Final Answer:

    Option A -> Option A
  4. Quick Check:

    Dijkstra's variant correctly handles max edge cost minimization [OK]
Hint: Minimize max edge cost -> Dijkstra variant [OK]
Common Mistakes:
  • Assuming greedy local choice leads to global optimum
  • Using sum of efforts instead of max
  • Exhaustive DFS is too slow
4. Examine the following buggy code snippet for bidirectional BFS to find the shortest path in a binary matrix. Which line contains the subtle bug that can cause infinite loops or incorrect results?
def visit(queue, visited, other_visited):
    r, c = queue.popleft()
    for dr, dc in directions:
        nr, nc = r + dr, c + dc
        if 0 <= nr < n and 0 <= nc < n and grid[nr][nc] == 0:
            if (nr, nc) in other_visited:
                return visited[(r, c)] + other_visited[(nr, nc)]
            if (nr, nc) not in visited:
                queue.append((nr, nc))  # Bug here
                # Missing visited marking here
    return None
medium
A. Line where the current cell is popped from the queue
B. Line where the cell is checked if in other_visited
C. Line where neighbors are checked for grid boundaries
D. Line where neighbor is appended to queue without marking visited

Solution

  1. Step 1: Identify visited marking usage

    Visited must be marked when neighbor is enqueued to avoid revisiting.
  2. Step 2: Locate missing visited marking

    Neighbor is appended to queue but not marked visited, causing possible infinite revisits.
  3. Final Answer:

    Option D -> Option D
  4. Quick Check:

    Marking visited on enqueue prevents infinite loops [OK]
Hint: Mark visited when enqueuing neighbors [OK]
Common Mistakes:
  • Mark visited only when dequeuing
  • Forgetting visited marking entirely
5. Suppose the graph edges can be reused multiple times (multi-edges allowed) and self-loops exist. Which modification to the bipartite check algorithm is necessary to correctly handle this variant?
hard
A. Reject any graph with self-loops immediately as non-bipartite
B. Modify Union-Find to union each edge multiple times without changes
C. Use BFS coloring but skip nodes with self-loops to avoid conflicts
D. Ignore self-loops and treat multi-edges as single edges before running BFS or Union-Find

Solution

  1. Step 1: Understand the impact of self-loops on bipartiteness

    A self-loop connects a vertex to itself, making it impossible to assign two different colors, so the graph is not bipartite.
  2. Step 2: Recognize that multi-edges do not affect bipartiteness if handled properly

    Multi-edges can be treated as single edges; they don't create odd cycles by themselves.
  3. Step 3: Conclude that immediate rejection on self-loops is necessary

    Any presence of self-loops means the graph cannot be bipartite, so the algorithm must detect and reject such graphs upfront.
  4. Final Answer:

    Option A -> Option A
  5. Quick Check:

    Self-loops break bipartite property immediately [OK]
Hint: Self-loops always break bipartite property [OK]
Common Mistakes:
  • Ignoring self-loops
  • Trying to color self-looped nodes
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard