207. 课程表
package leetcode.top100;
import java.util.*;
public class Timetable {
public static boolean canFinish(int numCourses, int[][] prerequisites) {
/**
* 核心思想是用类似广度优先遍历
* 1.先遍历prerequisites数组,计算入度。
*
*/
// 1.计算课程号和其对应节点的入度
HashMap<Integer, Integer> inDegree = new HashMap<>();
// 将课程放入
for (int i = 0; i < numCourses; i++) {
inDegree.put(i,0);
}
//2.依赖关系。存储依赖关系
HashMap<Integer, List<Integer>> adj = new HashMap<>();
// 初始化入度和依赖关系 a.算出每个节点的入度。 b.算出每个节点是谁的上个节点,也就是谁的先修课
for (int[] relate : prerequisites){
// (3,0), 想学3号课程要先完成0号课程, 更新3号课程的入度和0号课程的依赖(邻接表)
int cur = relate[0];
int before = relate[1];
// (1).更新入度
inDegree.put(cur,inDegree.get(cur)+1);
// 2.当前节点的邻接表
if (!adj.containsKey(before)){
adj.put(before,new ArrayList<>());
}
adj.get(before).add(cur);
}
// 3.BFS, 将入度为0的课程放入队列, 队列中的课程就是没有先修, 可以学的课程
Queue<Integer> queue = new LinkedList<>();
for (int key:inDegree.keySet()){
if (inDegree.get(key)==0){
queue.add(key);
}
}
// 取出一个节点, 对应学习这门课程.
// 遍历当前邻接表, 更新其入度; 更新之后查看入度, 如果为0, 加入到队列
while (!queue.isEmpty()){
Integer cur = queue.poll();
// 遍历当前课程的邻接表, 更新后继节点的入度
if (!adj.containsKey(cur)){
continue;
}
// 当前节点代表课程是哪些课程先修课
List<Integer> impactList = adj.get(cur);
for (int k:impactList){
inDegree.put(k,inDegree.get(k)-1);
if (inDegree.get(k)==0){
queue.add(k);
}
}
}
// 4.遍历入队, 如果还有课程的入度不为0, 返回fasle
for (int key:inDegree.keySet()){
if (inDegree.get(key)!=0){
return false;
}
}
return true;
}
public static void main(String[] args) {
int[][] course = new int[][]{
{1,0}
};
boolean res = canFinish(6, course);
System.out.println(res);
}
}
作者:静默虚空
欢迎任何形式的转载,但请务必注明出处。
限于本人水平,如果文章和代码有表述不当之处,还请不吝赐教。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· .NET10 - 预览版1新功能体验(一)
2022-05-15 idea 解决查看源码没有注释