Practice
Solution
Step 1: Understand the problem constraints
The problem requires finding the cheapest flight with at most K stops, which limits path length and requires considering multiple paths.Step 2: Identify suitable algorithm
Greedy Dijkstra fails because it doesn't limit stops; DFS is exponential; topological sort requires DAG which flights graph may not be. Bottom-up DP iterates over stops and relaxes edges, guaranteeing optimal cost within K stops.Final Answer:
Option D -> Option DQuick Check:
Bottom-up DP with stops limit ensures optimal solution [OK]
- Using Dijkstra without stop limit
- Trying DFS without pruning
- Assuming DAG for topological sort
def findCheapestPrice(n, flights, src, dst, K):
INF = float('inf')
prev = [INF] * n
prev[src] = 0
for _ in range(K + 1):
curr = prev[:]
for u, v, w in flights:
if prev[u] != INF:
curr[v] = min(curr[v], prev[u] + w)
prev = curr
return prev[dst] if prev[dst] != INF else -1
print(findCheapestPrice(n, flights, src, dst, K))Solution
Step 1: Trace dp arrays for each iteration
Initially prev = [0, inf, inf]. After first iteration (0 stops), curr updates cost to city 1 as 100 and city 2 as 500. After second iteration (1 stop), curr updates city 2 cost to min(500, 100 + 100) = 200.Step 2: Return final cost for destination
prev[2] after K+1=2 iterations is 200, which is the cheapest cost with at most 1 stop.Final Answer:
Option B -> Option BQuick Check:
DP updates costs correctly over K+1 iterations [OK]
- Returning direct edge cost ignoring stops
- Off-by-one in iteration count
- Confusing curr and prev arrays
Solution
Step 1: Understand problem constraints and properties
The problem requires finding a minimum path sum with overlapping subproblems and optimal substructure, which suits dynamic programming.Step 2: Identify suitable algorithm
Bottom-up DP tabulation efficiently computes minimum sums from the bottom row up, avoiding recomputation and ensuring optimality.Final Answer:
Option D -> Option DQuick Check:
DP tabulation solves overlapping subproblems efficiently [OK]
- Assuming greedy choice is always optimal
- Using brute force recursion without memoization
- Trying to split triangle independently ignoring dependencies
n vertices?Solution
Step 1: Identify loops in the code
There are three nested loops: length (up to n), i (up to n), and k (up to n), each iterating up to n times.Step 2: Calculate total complexity
Multiplying these loops gives O(n * n * n) = O(n^3). No extra log factor or higher power arises.Final Answer:
Option C -> Option CQuick Check:
Three nested loops over n vertices -> cubic time [OK]
- Confusing recursion stack space
- Assuming only two nested loops
- Adding unnecessary log factors
Solution
Step 1: Understand diagonal move impact
Diagonal moves depend on the top-left neighbor dp[i-1][j-1], which cannot be tracked with a single 1D array.Step 2: Choose correct DP structure
A 2D DP array is needed to access dp[i-1][j-1] directly; update rule: dp[i][j] = dp[i-1][j] + dp[i][j-1] + dp[i-1][j-1].Step 3: Reject incorrect options
Update dp[j] as dp[j] + dp[j - 1] + dp[j - 2] in the inner loop incorrectly accesses dp[j-2] in 1D array which doesn't represent diagonal; Keep the 1D dp array and update dp[j] = dp[j] + dp[j - 1] only, ignoring diagonal moves ignores diagonal; Use recursion without memoization to handle the extra diagonal move is inefficient.Final Answer:
Option A -> Option AQuick Check:
Diagonal requires 2D DP for correct neighbor access [OK]
- Trying to handle diagonal with 1D DP
- Ignoring diagonal moves in update
