拓扑排序leetcode
时间: 2025-01-11 08:49:37 浏览: 32
### LeetCode 拓扑排序题目解析
#### 课程表 (Course Schedule)
在LeetCode上的经典问题之一是《课程表》[^4]。该问题描述如下:
给定 `n`门课程以及一些先修课的要求,判断是否可以完成所有课程的学习。
##### 思路分析
这个问题可以通过检测是否存在有向无环图(DAG)来解决。具体来说,如果能够找到一种拓扑排序方式,则意味着这些课程是可以按照一定顺序全部学完的;反之如果有环存在,则无法完成所有的课程学习。
为了实现这一点,通常会采用邻接矩阵或者邻接表的形式构建图结构,并利用深度优先搜索(DFS)[^2] 或广度优先搜索(BFS)[^1] 来尝试获得一个有效的拓扑序列。
对于BFS方法,在初始化阶段需要找出入度为零的节点加入队列中作为起点,之后不断移除当前处理过的节点并更新其他相连节点的入度直到遍历结束或发现矛盾为止[^5]。
```java
public boolean canFinish(int numCourses, int[][] prerequisites) {
List<Integer>[] adj = new ArrayList[numCourses];
int[] indegrees = new int[numCourses];
// 构建邻接表和计算各结点入度数
for (int[] edge : prerequisites) {
if (adj[edge[1]] == null)
adj[edge[1]] = new ArrayList<>();
adj[edge[1]].add(edge[0]);
++indegrees[edge[0]];
}
Queue<Integer> queue = new LinkedList<>();
// 将所有入度为0的顶点入队
for (int i = 0; i < numCourses; ++i){
if(indegrees[i]==0)queue.offer(i);
}
while(!queue.isEmpty()){
Integer cur=queue.poll();
--numCourses;
if(adj[cur]!=null){
for(Integer next:adj[cur]){
if(--indegrees[next]==0){
queue.offer(next);
}
}
}
}
return numCourses==0;
}
```
这段代码实现了基于Kahn算法(即宽度优先搜索)来进行拓扑排序的过程。它首先统计每个节点的入度数目,并把那些没有任何前驱依赖关系(也就是入度等于0)的节点放进初始队列里。接着逐个取出队首元素进行访问操作——减少其指向的目标节点们的剩余未满足条件数量(即减去它们各自的入度值)。一旦某个目标节点变得不再受约束(它的新入度变为0),就立即将这个节点追加到待处理集合当中继续考察下去。最终当整个流程结束后,只要还剩下没被触及过的东西就意味着原图中含有至少一个闭环路径,从而导致任务失败;否则便成功找到了一组可行方案。
阅读全文
相关推荐
















