Video 1: Dijkstras Shortest Path Algorithm Explained | With Example | Graph Theory
Channel: FelixTechTips
Watch on YouTube →Algorithm • extra hard
Dijkstra computes shortest paths from one source in graphs with non-negative edge weights.
It repeatedly picks the currently cheapest frontier node using a min-priority queue.
When weights can be negative, use Bellman-Ford or other alternatives instead.
Typical Complexity Baseline
| Metric | Value |
|---|---|
| Complexity Note 1 | O((V + E) log V) with heap |
See It
A small animated SVG that illustrates the core idea the moving parts you need to keep in your head when you read the rest of the guide.
The greedy choice always relaxes the closest unvisited node. Highlighted edges form the shortest path.
Watch First
A quick visual walkthrough before the detailed sections pick the format that helps you learn fastest.
Channel: FelixTechTips
Watch on YouTube →Channel: Computerphile
Watch on YouTube →Channel: Shradha Khapra
Watch on YouTube →Channel: b001
Watch on YouTube →Mechanics
The building blocks and terminology you need before everything else clicks. Skim or deep-read.
What it is Best-known distance from source to each node.
Why it matters Distance array is a required building block for understanding how Dijkstra Shortest Path stays correct and performant on large inputs.
What it is Frontier by smallest current distance.
Why it matters Priority queue is a required building block for understanding how Dijkstra Shortest Path stays correct and performant on large inputs.
What it is Try improving neighbor distance via current node. Update distance if new path is cheaper.
Why it matters Relaxation is a required building block for understanding how Dijkstra Shortest Path stays correct and performant on large inputs. Update distance if new path is cheaper. In Dijkstra Shortest Path, this definition helps you reason about correctness and complexity when inputs scale.
What it is Optional optimization to skip stale states.
Why it matters Visited/finalized set is a required building block for understanding how Dijkstra Shortest Path stays correct and performant on large inputs.
What it is Outgoing weighted edges per node.
Why it matters Adjacency list is a required building block for understanding how Dijkstra Shortest Path stays correct and performant on large inputs.
What it is Queue entry whose distance no longer matches best known value.
Why it matters Queue entry whose distance no longer matches best known value. In Dijkstra Shortest Path, this definition helps you reason about correctness and complexity when inputs scale.
What it is Edge cost >= 0 required for Dijkstra correctness.
Why it matters Edge cost >= 0 required for Dijkstra correctness. In Dijkstra Shortest Path, this definition helps you reason about correctness and complexity when inputs scale.
What it is Shortest paths from one source to all nodes.
Why it matters Shortest paths from one source to all nodes. In Dijkstra Shortest Path, this definition helps you reason about correctness and complexity when inputs scale.
What it is Parent pointers describing chosen shortest paths.
Why it matters Parent pointers describing chosen shortest paths. In Dijkstra Shortest Path, this definition helps you reason about correctness and complexity when inputs scale.
Walkthrough
Every frame of the concept diagram, laid out top-to-bottom so you can scroll through the algorithm at your own pace.
Init: dist[S] = 0, every other node = ∞.
Visit S (d=0). Relax → A→2, B→5.
Visit A (d=2). Relax → C→5, D→6.
Visit B (d=5). Relax → E→11.
Visit C (d=5). Relax → E→8.
Visit D (d=6). Relax → T→11.
Visit E (d=8). Relax → T→10.
Visit T (d=10). No improvements.
Done. Shortest path S → T has total cost 10.
Tradeoffs
When this technique wins, when it loses, and what to reach for instead.
Choose this when Choose Dijkstra when edge weights differ.
Tradeoff BFS is faster/simpler for unweighted graphs.
Choose this when Choose Dijkstra for non-negative weights and better performance.
Tradeoff Bellman-Ford supports negative edges at higher cost.
Choose this when Choose Dijkstra when no admissible heuristic is available.
Tradeoff A* can be faster toward single target with good heuristic.
In Production
Where this shows up at real companies and what the on-call engineer learned the hard way.
Route planning systems rely on shortest-path families including Dijkstra-style expansion phases.
Takeaway Weighted graph pathing is core in location products.
Link-state routing protocols historically use Dijkstra-like SPF computations.
Takeaway Internet infrastructure uses shortest-path algorithms in control planes.
ETA and routing services evaluate weighted travel graphs continuously.
Takeaway Path-cost optimization directly affects product quality.
Code
A clean reference implementation in TypeScript, Python, and Go. Switch languages with the toggle.
Use min-priority frontier and relax edges from cheapest-known node each step.
Complexity: O((V+E) log V) with binary heap
Dijkstra shortest distances
type WeightedEdge = { edgeWeight: number; neighborNode: number }
type HeapNode = { distance: number; node: number }
class MinDistanceHeap {
private readonly values: HeapNode[] = []
push(params: HeapNode): void {
this.values.push(params)
this.bubbleUp(this.values.length - 1)
}
pop(): HeapNode | null {
if (this.values.length === 0) return null
const rootValue = this.values[0]
const lastValue = this.values.pop()
if (this.values.length > 0 && lastValue) {
this.values[0] = lastValue
this.bubbleDown(0)
}
return rootValue
}
private bubbleUp(startIndex: number): void {
let currentIndex = startIndex
while (currentIndex > 0) {
const parentIndex = Math.floor((currentIndex - 1) / 2)
if (this.values[parentIndex].distance <= this.values[currentIndex].distance) break
;[this.values[parentIndex], this.values[currentIndex]] = [this.values[currentIndex], this.values[parentIndex]]
currentIndex = parentIndex
}
}
private bubbleDown(startIndex: number): void {
let currentIndex = startIndex
while (true) {
const leftChildIndex = currentIndex * 2 + 1
const rightChildIndex = currentIndex * 2 + 2
let smallestIndex = currentIndex
if (leftChildIndex < this.values.length && this.values[leftChildIndex].distance < this.values[smallestIndex].distance) {
smallestIndex = leftChildIndex
}
if (rightChildIndex < this.values.length && this.values[rightChildIndex].distance < this.values[smallestIndex].distance) {
smallestIndex = rightChildIndex
}
if (smallestIndex === currentIndex) break
;[this.values[currentIndex], this.values[smallestIndex]] = [this.values[smallestIndex], this.values[currentIndex]]
currentIndex = smallestIndex
}
}
}
function dijkstraShortestDistances(params: { adjacencyByNode: WeightedEdge[][]; sourceNode: number }): number[] {
const distanceByNode = new Array<number>(params.adjacencyByNode.length).fill(Number.POSITIVE_INFINITY)
distanceByNode[params.sourceNode] = 0
const frontierHeap = new MinDistanceHeap()
frontierHeap.push({ distance: 0, node: params.sourceNode })
while (true) {
const nextEntry = frontierHeap.pop()
if (!nextEntry) break
if (nextEntry.distance !== distanceByNode[nextEntry.node]) {
continue
}
for (const edge of params.adjacencyByNode[nextEntry.node]) {
const candidateDistance = nextEntry.distance + edge.edgeWeight
if (candidateDistance < distanceByNode[edge.neighborNode]) {
distanceByNode[edge.neighborNode] = candidateDistance
frontierHeap.push({ distance: candidateDistance, node: edge.neighborNode })
}
}
}
return distanceByNode
}
Watch Out
The bugs and edge cases that bite engineers most often. Skim before you ship.
Pro Tips
Small habits that pay off every time you reach for this pattern.
Pattern Recognition
Concrete signals that tell you this is the right pattern both at work and on LeetCode.
Practice
A curated easy-to-hard problem ladder. Each one reinforces a specific aspect of the pattern.
| # | Problem | Difficulty | Typical Complexity |
|---|---|---|---|
| 1 | Network Delay Time | Medium | O((V+E) log V) |
| 2 | Path With Minimum Effort | Medium | O((V+E) log V) |
| 3 | Cheapest Flights Within K Stops | Medium | Varies |
| 4 | Number of Ways to Arrive at Destination | Medium | O((V+E) log V) |
| 5 | The Maze II | Medium | O((V+E) log V) |
| 6 | Swim in Rising Water | Hard | O(n^2 log n) |
| 7 | Minimum Cost to Reach Destination in Time | Hard | O((V+E) log V) |
| 8 | Reachable Nodes In Subdivided Graph | Hard | O((V+E) log V) |
| 9 | Minimum Weighted Subgraph With the Required Paths | Hard | O((V+E) log V) |
| 10 | Second Minimum Time to Reach Destination | Hard | Graph shortest-path variant |