题目
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.
思路
这道题目是典型的图的拓扑排序题目,这里先简要介绍一下拓扑排序算法的实现步骤:
- 初始化图邻接矩阵(u依赖于于v,则matrix[u][v]==1)和每个节点的入度数组(u依赖于v,则indegree[v]++)。
- 从入度数组中选取一个没有前驱节点(即indegree[v]==0)的顶点输出。
- 从图中删除该顶点和所有以它为头节点的弧。(即所有matrix[v][otherV]==1的,indegre[otherV]–)。
- 重复2,3步骤,直到全部顶点均已输出,或者图中不存在无前驱的顶点为止.(此时说明图中有环)。
所以,这道题目就是检测最后构造的图中是否有环即可(即检测indegree数组是否有顶点的值大于0)。
AC Code
ac代码如下所示:
public class Solution {
public boolean canFinish(int numCourses, int[][] prerequisites) {
boolean canFinish = true;
int[] indegree = new int[numCourses];
int[][] matrix = new int[numCourses][numCourses];
// initial data
for (int i = 0; i < prerequisites.length; i ++) {
if (matrix[prerequisites[i][0]][prerequisites[i][1]] == 1) continue;
indegree[prerequisites[i][1]] ++;
matrix[prerequisites[i][0]][prerequisites[i][1]] = 1;
}
// topological sort
for (int i = 0; i < numCourses; i ++) {
for (int j = 0; j < numCourses; j ++) {
if (indegree[j] == 0) {
indegree[j] --;
// delete node which start is j
for (int k = 0; k < numCourses; k ++) {
if (matrix[j][k] == 1) {
indegree[k] --;
matrix[j][k] = 0;
}
}
break;
}
}
}
// output result
for (int i = 0; i < numCourses; i ++) {
if (indegree[i] > 0) {
canFinish = false;
break;
}
}
return canFinish;
}
}
时间: 2024-10-15 04:59:26