Dijkstra's Algorithm Single Source Shortest Path in DSA Javascript - Time & Space Complexity
We want to understand how the time needed to find shortest paths grows as the graph gets bigger.
How does the algorithm's work increase when there are more nodes and edges?
Analyze the time complexity of the following code snippet.
function dijkstra(graph, start) {
const distances = {};
const visited = new Set();
const pq = new MinPriorityQueue();
for (const node in graph) distances[node] = Infinity;
distances[start] = 0;
pq.enqueue(start, 0);
while (!pq.isEmpty()) {
const { element: current } = pq.dequeue();
if (visited.has(current)) continue;
visited.add(current);
for (const neighbor in graph[current]) {
const newDist = distances[current] + graph[current][neighbor];
if (newDist < distances[neighbor]) {
distances[neighbor] = newDist;
pq.enqueue(neighbor, newDist);
}
}
}
return distances;
}
This code finds the shortest path from one node to all others using a priority queue and updates distances step by step.
Look for loops and repeated steps that take most time.
- Primary operation: The while loop runs until all nodes are visited, and inside it, the for loop checks neighbors of the current node.
- How many times: The while loop runs up to V times (number of nodes), and the inner for loop runs for all edges connected to nodes, totaling E times (number of edges).
As the graph grows, the number of nodes (V) and edges (E) increase, affecting the work done.
| Input Size (V, E) | Approx. Operations |
|---|---|
| 10 nodes, 20 edges | About 10 dequeue operations and 20 neighbor checks |
| 100 nodes, 500 edges | About 100 dequeue operations and 500 neighbor checks |
| 1000 nodes, 5000 edges | About 1000 dequeue operations and 5000 neighbor checks |
Pattern observation: The work grows roughly with the number of nodes plus edges, so bigger graphs mean more steps.
Time Complexity: O((V + E) log V)
This means the time grows with nodes and edges, multiplied by the cost of managing the priority queue, which depends on nodes.
[X] Wrong: "Dijkstra's algorithm always runs in simple linear time O(V + E)."
[OK] Correct: Managing the priority queue adds a log factor, so the actual time depends on log V too, making it slower than just linear.
Understanding this time complexity helps you explain how efficient your solution is and why certain data structures matter.
"What if we used a simple array instead of a priority queue? How would the time complexity change?"
Practice
Solution
Step 1: Understand the algorithm's goal
Dijkstra's Algorithm is designed to find the shortest paths from one starting point (source) to all other points in a graph with non-negative edge weights.Step 2: Compare with other graph algorithms
Other algorithms like max flow or cycle detection serve different purposes, so they do not match Dijkstra's goal.Final Answer:
To find the shortest path from a single source to all other vertices -> Option DQuick Check:
Shortest path from one source = To find the shortest path from a single source to all other vertices [OK]
- Confusing Dijkstra with max flow algorithms
- Thinking it detects cycles
- Assuming it sorts vertices
Solution
Step 1: Understand distance initialization
Distances to all nodes except the source should start as Infinity to represent unknown paths, and the source distance is 0.Step 2: Check each option
const dist = new Array(n).fill(Infinity); dist[source] = 0; correctly sets all distances to Infinity and source to 0. Others either set wrong initial values or invert source distance.Final Answer:
const dist = new Array(n).fill(Infinity); dist[source] = 0; -> Option AQuick Check:
Distance array starts with Infinity except source = const dist = new Array(n).fill(Infinity); dist[source] = 0; [OK]
- Setting source distance to Infinity
- Using 0 for all distances initially
- Using null or -1 incorrectly
const graph = {
0: [{node:1, weight:4}, {node:2, weight:1}],
1: [{node:3, weight:1}],
2: [{node:1, weight:2}, {node:3, weight:5}],
3: []
};
const dist = [0, Infinity, Infinity, Infinity];
const visited = new Set();
function dijkstra() {
while (visited.size < 4) {
let u = -1;
let minDist = Infinity;
for (let i = 0; i < 4; i++) {
if (!visited.has(i) && dist[i] < minDist) {
minDist = dist[i];
u = i;
}
}
visited.add(u);
for (const neighbor of graph[u]) {
if (dist[u] + neighbor.weight < dist[neighbor.node]) {
dist[neighbor.node] = dist[u] + neighbor.weight;
}
}
}
}
dijkstra();
console.log(dist);Solution
Step 1: Trace initial distances and first iteration
Start dist = [0, Infinity, Infinity, Infinity]. Pick node 0 (dist=0). Update neighbors: node 1 = 4, node 2 = 1.Step 2: Next iterations and updates
Pick node 2 (dist=1). Update node 1: min(4, 1+2=3) = 3; node 3: min(Infinity, 1+5=6) = 6. Pick node 1 (dist=3). Update node 3: min(6, 3+1=4) = 4. Pick node 3 (dist=4). No neighbors.Final Answer:
[0, 3, 1, 4] -> Option BQuick Check:
Distances after updates = [0, 3, 1, 4] [OK]
- Not updating distances correctly
- Choosing wrong next node
- Ignoring neighbor updates
const dist = new Array(n).fill(Infinity);
dist[source] = 0;
const visited = new Set();
while (visited.size < n) {
let u = -1;
let minDist = Infinity;
for (let i = 0; i < n; i++) {
if (dist[i] < minDist) {
minDist = dist[i];
u = i;
}
}
visited.add(u);
for (const neighbor of graph[u]) {
if (dist[u] + neighbor.weight < dist[neighbor.node]) {
dist[neighbor.node] = dist[u] + neighbor.weight;
}
}
}Solution
Step 1: Analyze node selection loop
The loop selects node u with smallest dist[i] but does not check if i is already visited, so it may pick visited nodes again.Step 2: Understand impact of missing visited check
Without skipping visited nodes, the algorithm can loop incorrectly or update distances wrongly, breaking correctness.Final Answer:
The code does not check if node i is already visited before selecting u -> Option CQuick Check:
Must skip visited nodes when picking u = The code does not check if node i is already visited before selecting u [OK]
- Forgetting to check visited nodes in selection
- Incorrect distance initialization
- Not updating visited set
- 0 -> 1 (2)
- 0 -> 2 (4)
- 1 -> 2 (1)
- 1 -> 3 (7)
- 2 -> 4 (3)
- 3 -> 4 (1)
Using Dijkstra's Algorithm from source node 0, what is the shortest distance to node 4?
Solution
Step 1: Trace shortest paths from node 0
Start dist: 0=0, others=Infinity. From 0: dist[1]=2, dist[2]=4.Step 2: Update distances via neighbors
From 1: dist[2]=min(4,2+1=3)=3, dist[3]=2+7=9. From 2: dist[4]=3+3=6. From 3: dist[4]=min(6,9+1=10)=6.Final Answer:
6 -> Option AQuick Check:
Shortest distance to node 4 = 6 [OK]
- Ignoring shorter path through node 2
- Adding wrong edge weights
- Not updating distances properly
Ready to prove it?
Pass the test and this pattern moves unknown
