Initialize the 'prev' cost array with infinity for all cities except the source city 0, which is set to 0. This represents the cost to reach each city with 0 stops.
💡 Setting the source cost to zero establishes the base case for DP; all other cities are initially unreachable.
💡 The algorithm keeps the minimum cost found so far.
shrink
Finish iteration 2 and swap arrays
Finish relaxing all edges for iteration 2. Swap prev and curr so prev now holds the final updated costs.
💡 Swapping arrays finalizes costs after allowing up to K stops.
Line:prev = curr
💡 The DP arrays now contain the minimum costs with up to K stops.
reconstruct
Return final answer
Return the cost to reach destination city 2 from prev array. Since prev[2] = 200, return 200 as the cheapest price within K stops.
💡 The final DP array holds the answer after all relaxations.
Line:return prev[dst] if prev[dst] != INF else -1
💡 The DP approach successfully finds the minimum cost path with constraints.
def findCheapestPrice(n, flights, src, dst, K):
INF = float('inf')
prev = [INF] * n # STEP 1
prev[src] = 0 # STEP 1
for _ in range(K + 1): # STEP 2
curr = prev[:] # STEP 2
for u, v, w in flights: # STEP 3-5,8-10
if prev[u] != INF:
curr[v] = min(curr[v], prev[u] + w)
prev = curr # STEP 6,11
return prev[dst] if prev[dst] != INF else -1 # STEP 12
if __name__ == '__main__':
n = 3
flights = [[0,1,100],[1,2,100],[0,2,500]]
src = 0
dst = 2
K = 1
print(findCheapestPrice(n, flights, src, dst, K)) # Output: 200
📊
Cheapest Flights Within K Stops - Watch the Algorithm Execute, Step by Step
Watching each relaxation and update helps you understand how dynamic programming propagates minimum costs through the graph over iterations.
Step 1/12
·Active fill★Answer cell
Visiting: none
0
1
2
Visiting: none
0
1
2
Visiting: 0
Edge: 0 → 1
0
1
2
Visiting: 1
Edge: 1 → 2
0
1
2
Visiting: 0
Edge: 0 → 2
0
1
2
Visiting: none
0
1
2
Visiting: none
0
1
2
Visiting: 0
Edge: 0 → 1
0
1
2
Visiting: 1
Edge: 1 → 2
0
1
2
Visiting: 0
Edge: 0 → 2
0
1
2
Visiting: none
0
1
2
Visiting: 2
0
1
2
Key Takeaways
✓ Dynamic programming propagates minimum costs through the graph by iteratively relaxing edges up to K+1 times.
This iterative relaxation is hard to visualize from code alone but becomes clear when watching each edge update step.
✓ The algorithm maintains two arrays to avoid using updated values within the same iteration, ensuring correctness.
Seeing the copy and swap of arrays clarifies why we don't update costs in place during relaxation.
✓ Relaxation only updates costs if the source city is reachable in the previous iteration, preventing invalid paths.
This conditional check is subtle in code but critical to understand how unreachable nodes don't affect costs.
Practice
(1/5)
1. You are given a connected undirected graph where each node contains a value and a list of its neighbors. The task is to create a deep copy of this graph such that the cloned graph has the same structure but no shared nodes with the original. Which algorithmic approach guarantees an optimal solution that handles cycles and multiple components correctly?
easy
A. Use a brute force DFS that recursively clones neighbors without tracking visited nodes.
B. Use BFS or DFS with a hash map to track visited nodes and clone each node exactly once.
C. Use a greedy approach that clones nodes only when their values are unique.
D. Use dynamic programming to store intermediate clone results indexed by node values.
Solution
Step 1: Understand the problem constraints
The graph may contain cycles and multiple components, so naive recursion can cause infinite loops or duplicate clones.
Step 2: Identify the correct approach
Using BFS or DFS with a hash map to track visited nodes ensures each node is cloned once, preventing infinite recursion and preserving graph structure.
Final Answer:
Option B -> Option B
Quick Check:
Tracking visited nodes avoids infinite loops and duplicates [OK]
Hint: Track visited nodes to avoid infinite recursion [OK]
Common Mistakes:
Not tracking visited nodes causes infinite recursion
Using node values as keys fails with duplicate values
2. You are given a 2D grid representing an image where each cell has a color value. Starting from a given pixel, you want to change the color of all connected pixels (4-directionally) that have the same original color to a new color. Which algorithmic approach guarantees an optimal solution for this problem?
easy
A. Sorting pixels by color and recoloring in order to minimize recoloring steps
B. Greedy approach that recolors pixels as soon as they are found without revisiting neighbors
C. Dynamic Programming to store intermediate recoloring states for each pixel
D. Depth-First Search (DFS) or Breadth-First Search (BFS) to explore all connected pixels with the original color
Solution
Step 1: Understand the problem as a connectivity search
The problem requires recoloring all pixels connected 4-directionally with the same original color starting from a given pixel.
Step 2: Identify the algorithm that explores connected components
DFS or BFS are standard graph traversal algorithms that explore all nodes reachable from a start node, which fits this problem perfectly.
Final Answer:
Option D -> Option D
Quick Check:
DFS/BFS ensures all connected pixels are visited exactly once [OK]
Hint: Flood fill is a graph traversal problem [OK]
Common Mistakes:
Thinking greedy recoloring works without full traversal
Confusing with DP which is not suitable here
3. Consider the following code snippet implementing the optimal BFS approach for the Surrounded Regions problem. Given the input board:
After the BFS marking completes, what is the value of board[3][1]?
easy
A. 'O'
B. 'X'
C. 'S'
D. IndexError (out of bounds)
Solution
Step 1: Identify boundary 'O's and mark them
Only board[3][1] is a boundary 'O', so it is marked 'S' and added to the queue.
Step 2: BFS expands from (3,1) marking connected 'O's
From (3,1), no adjacent 'O's inside the board are connected, so only (3,1) remains 'S'. After BFS, all 'S' revert to 'O'.
Final Answer:
Option A -> Option A
Quick Check:
Boundary 'O' at (3,1) remains 'O' after processing [OK]
Hint: Boundary 'O's remain 'O' after BFS marking [OK]
Common Mistakes:
Confusing 'S' with final 'O' or 'X' states.
Forgetting to revert 'S' back to 'O' after BFS.
Assuming all 'O's get flipped regardless of boundary connection.
4. Examine the following buggy code snippet for the optimal BFS approach. Which line contains the subtle bug that can cause incorrect results or infinite loops?
medium
A. Line that sets dist[nr][nc] = dist[r][c] + 1 without checking if dist[nr][nc] == -1
B. Line that initializes dist[r][c] = 0 for land cells
C. Line that appends initial land cells to the queue
D. Line that returns -1 if all cells are land or water
Solution
Step 1: Identify that updating dist[nr][nc] without checking if it was visited causes overwriting distances.
This leads to revisiting cells multiple times, causing infinite loops or incorrect distances.
Step 2: The missing condition dist[nr][nc] == -1 before updating and enqueueing is the bug.
Without it, BFS does not behave correctly as a shortest path search.
Final Answer:
Option A -> Option A
Quick Check:
Visited check prevents infinite loops and ensures correct distances [OK]
Hint: Always check if neighbor is unvisited before updating distance [OK]
Common Mistakes:
Forgetting visited check causes infinite loops
Misplacing initialization lines
Incorrect early return conditions
5. What is the time complexity of the optimal Dijkstra's algorithm variant solution for the minimum effort path problem on an n x m grid?
medium
A. O(n * m^2)
B. O(n * m * log(n * m))
C. O((n * m)^2)
D. O(n * m)
Solution
Step 1: Identify graph size
The grid has n*m nodes and up to 4 edges per node, so edges E = O(n*m).
Step 2: Analyze Dijkstra's complexity
Using a min-heap, each node is pushed/popped at most once, heap operations cost O(log(n*m)), total O(n*m*log(n*m)).
Final Answer:
Option B -> Option B
Quick Check:
Log factor comes from heap operations on n*m nodes [OK]
Hint: Dijkstra on grid -> O(V log V) with V=n*m [OK]
Common Mistakes:
Confusing edges with nodes count
Assuming O(n*m^2) due to nested loops
Ignoring log factor from heap
Recommended
Ready to prove it?
Pass the test and this pattern moves unknownstrongwhile earning +1 Grip toward your certificate.