There are a total of n courses you have to take, labeled from 0
to n - 1
.
Some courses may have prerequisites, for example to take course 0 you have to first take course 1, which is expressed as a pair: [0,1]
Given the total number of courses and a list of prerequisite pairs, is it possible for you to finish all courses?
For example:
2, [[1,0]]
There are a total of 2 courses to take. To take course 1 you should have finished course 0. So it is possible.
2, [[1,0],[0,1]]
There are a total of 2 courses to take. To take course 1 you should have finished course 0, and to take course 0 you should also have finished course 1. So it is impossible.
题目解析:该题的意思是,第一个数字告诉你有n个顶点,后面的二位数组则是告诉你两个端点的前后置关系
后一个数是前一个数的前置条件
代码:
public class Solution {
public boolean canFinish(int numCourses, int[][] prerequisites) {
Set<Integer> zeroDegree = new HashSet<>();
int[] degree = new int[numCourses];
for (int row = 0; row < prerequisites.length; row++)
degree[prerequisites[row][0]]++;//得出某端点有几个前置要求
for (int i = 0; i < degree.length; i++)
if (degree[i] == 0) zeroDegree.add(i);//无前置要求则加入这个set
if (zeroDegree.isEmpty()) return false;//所有点都有前置要求 失败
while (!zeroDegree.isEmpty()) {//从入度为空的点开始,逐一搜寻以该点为前置条件的点,找到一个则减少一个该点的前置条件数,一直循环
Iterator<Integer> it = zeroDegree.iterator();
int course = it.next();
zeroDegree.remove(course);
for (int row = 0; row < prerequisites.length; row++) {
int[] edge = prerequisites[row];
if (edge[1] == course) {
degree[edge[0]]--;
if (degree[edge[0]] == 0) zeroDegree.add(edge[0]);
}
}
}
for (int i = 0; i < degree.length; i++)
if (degree[i] != 0) return false;//循环完毕后还有点的入度不为0则代表有循环
return true;
}
}