Skip to content

最短路径:Dijkstra 算法

场景引入

地图导航软件是如何计算最快路线的?从起点到终点有无数条路径,怎样高效找到最短的那条?

Dijkstra 算法就是解决单源最短路径问题的经典方法——从一个起点出发,找到到所有其他节点的最短距离。

最短路径示例

从 A 出发的最短距离:A=0, B=2, C=5(经B), D=3(经B)

核心思路

Dijkstra 本质是 BFS + 贪心:每次从未确定的节点中选择距离最小的,确定它的最短距离,然后更新它的邻居。用优先队列(最小堆)加速选择过程。

模板代码

javascript
function dijkstra(graph, start) {
  const n = graph.length;
  const dist = new Array(n).fill(Infinity);
  dist[start] = 0;

  // 最小堆:[距离, 节点]
  const heap = new MinHeap();
  heap.push([0, start]);

  while (heap.size() > 0) {
    const [d, node] = heap.pop();

    // 已经有更短的路径了,跳过
    if (d > dist[node]) continue;

    for (const [next, weight] of graph[node]) {
      const newDist = dist[node] + weight;
      if (newDist < dist[next]) {
        dist[next] = newDist;
        heap.push([newDist, next]);
      }
    }
  }

  return dist;
}

LC 743. 网络延迟时间

有 n 个节点和有向加权边,从节点 k 发送信号,返回所有节点收到信号的最短时间。如果不能到达所有节点,返回 -1。

javascript
function networkDelayTime(times, n, k) {
  const graph = Array.from({ length: n + 1 }, () => []);
  for (const [u, v, w] of times) {
    graph[u].push([v, w]);
  }

  const dist = dijkstra(graph, k, n);

  let maxDist = 0;
  for (let i = 1; i <= n; i++) {
    if (dist[i] === Infinity) return -1;
    maxDist = Math.max(maxDist, dist[i]);
  }
  return maxDist;
}

function dijkstra(graph, start, n) {
  const dist = new Array(n + 1).fill(Infinity);
  dist[start] = 0;
  // 简化:用数组模拟堆
  const pq = [[0, start]];

  while (pq.length) {
    pq.sort((a, b) => a[0] - b[0]);
    const [d, node] = pq.shift();
    if (d > dist[node]) continue;
    for (const [next, weight] of graph[node]) {
      if (dist[node] + weight < dist[next]) {
        dist[next] = dist[node] + weight;
        pq.push([dist[next], next]);
      }
    }
  }
  return dist;
}

注:面试时可用数组排序模拟堆。生产环境应使用真正的 MinHeap。

Dijkstra 的限制

  • 不能处理负权边。负权边可能导致已确定的最短距离被更新,破坏贪心策略。
  • 负权边需要用 Bellman-Ford 算法。

复杂度

实现时间
朴素(遍历找最小)O(V²)
优先队列优化O(E log V)

空间 O(V + E)。

LeetCode 练习

  • LC 743. 网络延迟时间 ⭐
  • LC 1514. 概率最大的路径
  • LC 1631. 最小体力消耗路径
  • LC 787. K 站中转内最便宜的航班

面试算法可视化图解