Bird
Raised Fist0
Interview Prepgraphs-dfs-bfsmediumAmazonGoogleFacebookBloomberg

Rotting Oranges

Choose your preparation mode4 modes available
▶
Steps
setup

Initialize time grid and max_time

Create a time grid initialized to -1 for all cells, indicating no rot time assigned yet. Initialize max_time to 0 to track the longest rot spread time.

💡 This setup prepares a parallel grid to record when each orange becomes rotten, essential for tracking propagation timing.
Line:time_grid = [[-1]*cols for _ in range(rows)] max_time = 0
💡 We need a separate structure to store rot times without modifying the original grid.
📊
Rotting Oranges - Watch the Algorithm Execute, Step by Step
Watching the step-by-step DFS traversal with time tracking reveals how the algorithm propagates rot and updates times, which is hard to grasp from code alone.
Step 1/12
·Active fill★Answer cell
Visiting: none
0,0
0,1
0,2
1,0
1,1
1,2
2,0
2,1
2,2
Visiting: 0,0
0,0
0,1
0,2
1,0
1,1
1,2
2,0
2,1
2,2
Queue / Stack
0,0
Visiting: 1,0
Edge: 0,0 → 1,0
0,0
1,0
0,1
0,2
1,1
1,2
2,0
2,1
2,2
Queue / Stack
1,00,0
Visiting: 1,1
Edge: 1,0 → 1,1
0,0
1,0
1,1
0,1
0,2
1,2
2,0
2,1
2,2
Queue / Stack
1,11,00,0
Visiting: 2,1
Edge: 1,1 → 2,1
0,0
1,0
1,1
2,1
0,1
0,2
1,2
2,0
2,2
Queue / Stack
2,11,11,00,0
Visiting: 2,2
Edge: 2,1 → 2,2
0,0
1,0
1,1
2,1
2,2
0,1
0,2
1,2
2,0
Queue / Stack
2,22,11,11,00,0
Visiting: 2,1
2,2
2,1
1,1
1,0
0,0
0,1
0,2
1,2
2,0
Queue / Stack
2,11,11,00,0
Visiting: 0,1
Edge: 0,0 → 0,1
0,0
0,1
0,2
1,0
1,1
2,1
2,2
1,2
2,0
Queue / Stack
0,10,0
Visiting: 0,2
Edge: 0,1 → 0,2
0,0
0,1
0,2
1,0
1,1
2,1
2,2
1,2
2,0
Queue / Stack
0,20,10,0
Visiting: none
0,0
0,1
0,2
1,0
1,1
2,1
2,2
1,2
2,0
Visiting: none
0,0
0,1
0,2
1,0
1,1
2,1
2,2
1,2
2,0
Visiting: none
0,0
0,1
0,2
1,0
1,1
2,1
2,2
1,2
2,0

Key Takeaways

✓ DFS with time tracking effectively models rot spread timing in a grid.

This insight is hard to see from code alone because the time updates and pruning conditions are subtle.

✓ The maximum time recorded corresponds to the longest path rot must travel to reach all fresh oranges.

Visualizing the time grid clarifies how rot propagation depends on grid layout and adjacency.

✓ DFS backtracking ensures all neighbors are explored and rot times updated only if earlier than previous.

Seeing the recursive calls and returns step-by-step reveals why some paths update times and others don't.

Practice

(1/5)
1. You need to find the cheapest route from a source city to a destination city with at most K stops in between. The graph edges represent flights with costs, and you want the minimum total cost under the stop constraint. Which algorithmic approach guarantees finding the optimal solution efficiently?
easy
A. Dynamic programming using a 2D table indexed by stops and cities without priority queue.
B. A simple DFS with backtracking exploring all paths up to K stops.
C. A greedy algorithm that always picks the cheapest next flight regardless of stops.
D. Dijkstra's algorithm modified to track the number of stops along with cost.

Solution

  1. Step 1: Understand the problem constraints

    The problem requires the cheapest path with at most K stops, so we must track both cost and stops.
  2. Step 2: Identify suitable algorithm

    Dijkstra's algorithm can be adapted to track stops as a state parameter, ensuring paths exceeding K stops are not considered, guaranteeing optimality efficiently.
  3. Final Answer:

    Option D -> Option D
  4. Quick Check:

    Modified Dijkstra tracks stops and cost simultaneously [OK]
Hint: Track stops in Dijkstra to enforce constraints [OK]
Common Mistakes:
  • Assuming greedy cheapest next flight always works
  • Using DFS without pruning leads to TLE
  • Ignoring stops count in shortest path
2. You are given a list of edges representing an undirected graph with n nodes labeled from 0 to n-1. You need to determine if the graph forms a valid tree. Which algorithmic approach guarantees an optimal solution to check both connectivity and absence of cycles efficiently?
easy
A. Use a greedy algorithm that adds edges one by one and checks if the graph remains connected.
B. Apply dynamic programming to count the number of ways to reach each node and detect cycles.
C. Sort edges and use binary search to detect cycles and connectivity.
D. Perform a BFS or DFS traversal to detect cycles and verify that all nodes are connected.

Solution

  1. Step 1: Understand problem requirements

    The problem requires checking if the graph is connected and contains no cycles, which defines a tree.
  2. Step 2: Identify suitable algorithm

    BFS or DFS traversal can detect cycles by tracking visited nodes and parent relationships, and also verify connectivity by ensuring all nodes are visited.
  3. Final Answer:

    Option D -> Option D
  4. Quick Check:

    BFS/DFS simultaneously checks connectivity and cycles efficiently [OK]
Hint: Trees have n-1 edges and no cycles [OK]
Common Mistakes:
  • Assuming greedy edge addition ensures connectivity
  • Using DP which is unrelated here
3. What is the time complexity of the optimal Dijkstra-based algorithm for finding the cheapest flight within K stops, given n cities and E flights? Assume the graph is represented as adjacency lists and a min-heap is used. A) O(n^2) because we may visit all nodes multiple times. B) O(E log E) because each edge can be pushed into the heap once. C) O(n log n) because Dijkstra runs in that time on sparse graphs. D) O(K * E) because we relax edges up to K times.
medium
A. O(n^2) because we may visit all nodes multiple times.
B. O(K * E) because we relax edges up to K times.
C. O(E log E) because each edge can be pushed into the heap once.
D. O(n log n) because Dijkstra runs in that time on sparse graphs.

Solution

  1. Step 1: Identify heap operations

    Each edge can be pushed into the heap at most once per stops count, but stops ≤ K limits pushes. The heap size is bounded by O(E).
  2. Step 2: Analyze complexity

    Each push/pop operation costs O(log E), so total time is O(E log E). The stops constraint prevents exponential blowup.
  3. Final Answer:

    Option C -> Option C
  4. Quick Check:

    Heap operations dominate; stops limit expansions [OK]
Hint: Heap operations on edges dominate complexity [OK]
Common Mistakes:
  • Assuming O(n^2) from classic Dijkstra on adjacency matrix
  • Ignoring that stops limit expansions
  • Confusing Bellman-Ford complexity with this approach
4. Examine the following buggy code for the Keys and Rooms problem:
def canVisitAllRooms(rooms):
    n = len(rooms)
    visited = [false] * n
    count = 0
    def dfs(room):
        if visited[room]:
            return
        for key in rooms[room]:
            dfs(key)
        visited[room] = true
        nonlocal count
        count += 1
    dfs(0)
    return count == n
What is the bug in this code?
medium
A. Visited marking happens after recursive calls, causing repeated visits
B. Count is incremented before marking visited, causing off-by-one errors
C. Visited array is initialized incorrectly with zeros instead of false
D. DFS is called on room 0 instead of all rooms

Solution

  1. Step 1: Analyze visited marking position

    Visited is marked after recursive calls, so the same room can be visited multiple times during recursion.
  2. Step 2: Identify consequence of bug

    This causes repeated visits and potentially infinite recursion or incorrect count.
  3. Final Answer:

    Option A -> Option A
  4. Quick Check:

    Visited must be marked before recursion to avoid revisits [OK]
Hint: Mark visited before recursion to prevent repeated visits [OK]
Common Mistakes:
  • Marking visited after recursion leads to infinite loops
  • Incrementing count before visited marking
  • Incorrect initialization of visited array
5. The following BFS code attempts to find the max area of an island in a grid. Identify the line that contains a subtle bug that can cause incorrect area calculation or runtime errors.
from collections import deque

def maxAreaOfIsland(grid):
    rows, cols = len(grid), len(grid[0])
    visited = set()
    max_area = 0

    for r in range(rows):
        for c in range(cols):
            if grid[r][c] == 1 and (r, c) not in visited:
                queue = deque([(r, c)])
                area = 0
                while queue:
                    row, col = queue.popleft()
                    # Bug: Missing visited check here
                    visited.add((row, col))
                    area += 1
                    for nr, nc in [(row+1,col),(row-1,col),(row,col+1),(row,col-1)]:
                        if grid[nr][nc] == 1 and (nr, nc) not in visited:
                            queue.append((nr, nc))
                max_area = max(max_area, area)
    return max_area
medium
A. Line that adds neighbors to the queue without boundary checks
B. Line that adds (row, col) to visited without checking if already visited
C. Line that initializes the queue with the starting cell
D. Line that updates max_area after BFS completes

Solution

  1. Step 1: Check neighbor addition line

    The code adds neighbors without verifying if nr, nc are within grid boundaries, risking index out of range errors.
  2. Step 2: Confirm other lines are correct

    Visited check before adding to queue is present, queue initialization and max_area update are correct.
  3. Final Answer:

    Option A -> Option A
  4. Quick Check:

    Boundary checks missing cause runtime errors [OK]
Hint: Always check grid boundaries before accessing neighbors [OK]
Common Mistakes:
  • Forgetting boundary checks
  • Not checking visited before adding to queue
  • Adding visited check after popping queue
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