By Fatskills Exam Guides Team — the exam nerds behind 28,500+ quizzes and 2.1M practice questions across 500+ global exams.
"Dijkstra’s algorithm isn’t just a graph problem—it’s a signal to interviewers that you can optimize real-world systems. Master it, and you’ll solve 1 in 4 graph problems in FAANG interviews while proving you understand trade-offs between time, space, and edge cases."
Before diving into Dijkstra’s, ensure you understand: 1. Priority Queues (Min-Heaps) – How to extract the smallest element in O(log n) time. 2. Graph Representations – Adjacency lists vs. adjacency matrices (and when to use each). 3. Breadth-First Search (BFS) – The intuition behind exploring nodes level by level.
heapq.heappop(pq)
dist[node] = min(dist[node], dist[current] + weight)
current_dist > dist[node]
dist[target]
{0: [(1, 4), (2, 1)], 1: [(3, 2)]}
node in visited
Run this exact sequence for every Dijkstra’s problem:
Sparse or dense? (Adjacency list for sparse, matrix for dense.)
Initialize Data Structures
dist
∞
dist[start] = 0
(0, start)
(Optional) visited set if the graph has cycles (rarely needed for Dijkstra’s).
visited
Process Nodes in Priority Order
While the queue isn’t empty:
current_dist, current_node
current_dist > dist[current_node]
new_dist = current_dist + edge_weight
new_dist < dist[neighbor]
dist[neighbor]
(new_dist, neighbor)
Terminate Early (If Applicable)
If the target node is popped from the queue, return dist[target] immediately.
Handle Edge Cases
0
-1
Multiple edges between nodes? (Keep the smallest weight.)
Return the Result
Problem: Given a graph with non-negative weights, find the shortest path from node 0 to node 3.
3
Graph:
0 --4--> 1 | | 1 2 | | 2 --3--> 3
Adjacency list:
graph = { 0: [(1, 4), (2, 1)], 1: [(3, 2)], 2: [(1, 2), (3, 3)], 3: [] }
Solution (Python):
import heapq def dijkstra(graph, start, target): dist = {node: float('inf') for node in graph} dist[start] = 0 pq = [(0, start)] while pq: current_dist, current_node = heapq.heappop(pq) if current_node == target: return current_dist if current_dist > dist[current_node]: continue # Lazy deletion for neighbor, weight in graph[current_node]: new_dist = current_dist + weight if new_dist < dist[neighbor]: dist[neighbor] = new_dist heapq.heappush(pq, (new_dist, neighbor)) return -1 # Target not reachable print(dijkstra(graph, 0, 3)) # Output: 4 (0 → 2 → 1 → 3)
Time Complexity: O((V + E) log V) (each edge processed once, heap operations take O(log V)). Space Complexity: O(V) (for dist and the heap).
Why This Works: - The priority queue ensures we always expand the closest node first. - Lazy deletion avoids reprocessing outdated entries. - The dist array guarantees we only update paths when we find a shorter one.
Problem: Find the shortest path from node 0 to all other nodes in the graph.
0 --1--> 1 --2--> 2 \ / 4 1 \ / 3
graph = { 0: [(1, 1), (3, 4)], 1: [(2, 2), (3, 1)], 2: [], 3: [] }
import heapq def dijkstra_all_nodes(graph, start): dist = {node: float('inf') for node in graph} dist[start] = 0 pq = [(0, start)] while pq: current_dist, current_node = heapq.heappop(pq) if current_dist > dist[current_node]: continue for neighbor, weight in graph[current_node]: new_dist = current_dist + weight if new_dist < dist[neighbor]: dist[neighbor] = new_dist heapq.heappush(pq, (new_dist, neighbor)) return dist print(dijkstra_all_nodes(graph, 0)) # Output: {0: 0, 1: 1, 2: 3, 3: 2}
Time Complexity: O((V + E) log V) (same as before). Space Complexity: O(V).
Why This Works: - The algorithm naturally computes shortest paths to all nodes. - The dist array is returned directly, giving distances to every node.
Problem: Given n cities (nodes) and flights (edges), find the cheapest price from src to dst with at most k stops.
n
src
dst
k
0 --100--> 1 --100--> 2 \ / 500 100 \ / 3
flights = [[0,1,100],[1,2,100],[0,3,500],[3,1,100]] n = 4 src = 0 dst = 2 k = 1
import heapq def findCheapestPrice(n, flights, src, dst, k): graph = {i: [] for i in range(n)} for u, v, w in flights: graph[u].append((v, w)) # Priority queue: (current_cost, current_node, stops_used) pq = [(0, src, 0)] # Track the minimum cost to reach each node with <= k stops min_cost = {node: float('inf') for node in range(n)} min_cost[src] = 0 while pq: cost, node, stops = heapq.heappop(pq) if node == dst: return cost if stops > k: continue for neighbor, weight in graph[node]: new_cost = cost + weight if new_cost < min_cost[neighbor]: min_cost[neighbor] = new_cost heapq.heappush(pq, (new_cost, neighbor, stops + 1)) return -1 print(findCheapestPrice(n, flights, src, dst, k)) # Output: 200 (0 → 1 → 2)
Time Complexity: O((V + E) log V) (same as Dijkstra’s, but with an extra constraint). Space Complexity: O(V).
Why This Works: - The priority queue now tracks (cost, node, stops), ensuring we respect the k stops limit. - We skip paths that exceed k stops, even if they’re cheaper (constraint handling).
(cost, node, stops)
new_dist
dist[target] == ∞
"Alright, let’s lock this in. Dijkstra’s is your go-to for shortest paths in graphs with non-negative weights. Here’s the playbook:
Remember: The priority queue is your best friend. Lazy deletion keeps you efficient. And if weights can be negative, pivot to Bellman-Ford. Now go crush that interview!
You’ve got this! ?
Join 4M+ learners. Unlock unlimited quizzes, wrong-answer tracking, flashcards + reminders, study guides, and 1-on-1 challenges.