📚 中大厂面试算法每日推荐
今日推荐算法:Dijkstra 最短路径算法
一、算法核心概述
Dijkstra算法是图论中最经典的单源最短路径算法,在有权图(权值非负数)中求从起点到其他所有节点的最短路径。该算法采用贪心思想,不断寻找距离源点最近的未访问节点,逐步扩展最短路径树。
二、关键特性对比
| 特性 | 说明 |
|---|---|
| 算法类型 | 单源最短路径 |
| 支持负权边 | ❌ 不支持 |
| 检测负权环 | ❌ 无法检测 |
| 时间复杂度 | O(m log n)(堆优化版) |
| 适合场景 | 无负权边的稀疏图,绝大多数面试题目首选 |
三、算法执行三部曲
- 选择最近节点:从源点出发,选择距离最近且未被访问过的节点
- 标记访问:将该节点标记为已访问
- 更新距离:更新所有未访问节点到源点的距离(即更新minDist数组)
四、核心代码模板(C++堆优化版)
cpp
// 邻接表存储图结构
vector<list<pair<int,int>>> g(n + 1);
// Dijkstra堆优化实现
priority_queue<pair<ll,ll>, vector<pair<ll,ll>>, greater<pair<ll,ll>>> pq;
pq.push({0, start}); // 起点距离为0
minDist[start] = 0;
while(!pq.empty()) {
pair<ll,ll> cur = pq.top();
pq.pop();
if(visited[cur.first]) continue;
visited[cur.first] = true;
for(Edge edge : g[cur.first]) {
ll v = edge.to;
ll w = edge.val;
if(!visited[v] && minDist[cur.first] + w < minDist[v]) {
minDist[v] = minDist[cur.first] + w;
pq.push({minDist[v], v});
}
}
}
五、面试高频追问点
根据C++技术面试高频考点分析,面试官通常会从以下四个层次考察:
- 语法机制层:能否正确实现优先队列的自定义比较函数
- 底层原理层:理解堆优化为何能将复杂度从O(n²)降至O(m log n)
- 工程设计层:如何处理大规模图数据的内存优化
- 算法素养层:能否对比Dijkstra与Bellman-Ford、SPFA的适用场景差异
六、同类算法对比
| 算法 | 单源/多源 | 支持负权 | 时间复杂度 | 面试频率 |
|---|---|---|---|---|
| Dijkstra | 单源 | ❌ | O(m log n) | ⭐⭐⭐⭐⭐ |
| Bellman-Ford | 单源 | ✅ | O(nm) | ⭐⭐⭐ |
| SPFA | 单源 | ✅ | 平均O(m) | ⭐⭐⭐ |
| Floyd-Warshall | 多源 | ✅ | O(n³) | ⭐⭐ |
七、实战建议
💡 面试技巧:不会做算法题时,可以主动说思路,哪怕只是暴力解。把暴力解的复杂度说清楚,然后说"我觉得可以优化到O(n log n),方向是排序或者二分",这种候选人通常比沉默到底的人拿到的评价高出一个档位。
📅 明日预告
明天将为您推荐快速排序算法,涵盖分区策略、时间复杂度分析及面试中的优化变种。
温馨提示:算法学习重在理解原理+手写代码+变式练习。建议今天完成以下任务:
- ✅ 理解Dijkstra的贪心思想
- ✅ 手写一遍堆优化代码
- ✅ 对比掌握其他三种最短路算法的适用边界
祝您面试顺利!🎯