Description
现在你总共有 n 门课需要选,记为 0
到 n - 1
.
一些课程在修之前需要先修另外的一些课程,比如要学习课程 0 你需要先学习课程 1 ,表示为[0,1]
给定n门课以及他们的先决条件,判断是否可能完成所有课程?
样例
给定 n = 2
,先决条件为 [[1,0]]
返回 true
给定 n = 2
,先决条件为 [[1,0],[0,1]]
返回 false
Solution
算法思路:
已知node和edge构造存储有向图图的map,有了map之后,剩下的解法类似于127.topological sorting 那道题
具体解法:
1. 把输入的参数转换成map形式存储的图
2. 拓扑排序得到list of result
3. 判断list中的节点个数是否为numCourses。因为拓扑排序节点入度为0时才会存入result,所以如果存在环,那么有向图的拓扑排序节点个数就会小于图的节点个数。
public class Solution {
/*
* @param numCourses: a total of n courses
* @param prerequisites: a list of prerequisite pairs
* @return: true if can finish all courses or false
*/
public boolean canFinish(int numCourses, int[][] prerequisites) {
// write your code here
// 已知node和edge构造存储有向图图的map
// 有了map之后,剩下的解法类似于topological sorting 那道题
// 思路:1.把输入的参数转换成map形式存储的图
// 2.拓扑排序得到list of result
// 3.判断list中的节点个数是否为numCourses
// 因为拓扑排序节点入度为0时才会存入result
// 所以如果存在环,那么有向图的拓扑排序节点个数就会小于图的节点个数
if (numCourses == 0 || prerequisites.length == 0) {
return true;
}
//创建courseMap
HashMap<Integer, List<Integer>> courseMap = creatCourseMap(numCourses, prerequisites);
//统计各个节点的入度
HashMap<Integer, Integer> indegreeMap = new HashMap<>();
for (int i = 0; i < numCourses; i++) {
for (Integer neighbor : courseMap.get(i)) {
if (indegreeMap.containsKey(neighbor)) {
indegreeMap.put(neighbor, indegreeMap.get(neighbor) + 1);
} else {
indegreeMap.put(neighbor, 1);
}
}
}
// 把所有入度为0的点,放到BFS专用的队列中
Queue<Integer> queue = new LinkedList<>();
// 初始化拓扑序列为空
ArrayList<Integer> result = new ArrayList<>();
for (int i = 0; i < numCourses; i++) {
if (!indegreeMap.containsKey(i)) {
queue.offer(i);
result.add(i);
}
}
// 每次从队列中拿出一个点放到拓扑序列里,并将该点指向的所有点的入度减1
while (!queue.isEmpty()) {
Integer course = queue.poll();
for (Integer neighbor : courseMap.get(course)) {
indegreeMap.put(neighbor, indegreeMap.get(neighbor) - 1);
// 减去1之后入度变为0的点,也放入队列
if (indegreeMap.get(neighbor) == 0) {
queue.offer(neighbor);
result.add(neighbor);
}
}
}
// 判断拓扑排序数与图的节点数是否相同
return result.size() == numCourses;
}
//创建courseMap有向图,方向为先修课程指向当前课程pre -> sou
private HashMap<Integer, List<Integer>> creatCourseMap(int numCourses, int[][] prerequisites) {
HashMap<Integer, List<Integer>> map = new HashMap<>();
for (int i = 0; i < numCourses; i++) {
map.put(i, new ArrayList<>());
}
for (int i = 0; i < prerequisites.length; i++) {
int sou = prerequisites[i][0];
int pre = prerequisites[i][1];
map.get(pre).add(sou);
}
return map;
}
}