207. 课程排序
给定一些课程,以及两两课程的前后顺序,判断能否修完所有的课。
思路:
很经典的拓扑排序问题。直接上代码:
public class Solution {
public boolean canFinish(int numCourses, int[][] prerequisites) {
int edge=prerequisites.length;
if(numCourses==0) return true;
if(edge==0) return true;
int[][] map=new int[numCourses][numCourses];
int[] indegree=new int[numCourses];
for(int i=0;i<edge;i++) {
int a=prerequisites[i][0];
int b=prerequisites[i][1];
if(map[b][a]==0) {
map[b][a]=1;
indegree[a]++;
}
}
toposort(map,indegree,numCourses);
if(count!=numCourses) return false;
return true;
}
int count=0;
void toposort(int map[][],int indegree[],int n) {
int i,j,k;
for(i=0;i<n;i++) { //遍历n次
for(j=0;j<n;j++) {//找出入度为0的节点
if(indegree[j]==0) {
indegree[j]--;
count++;
for(k=0;k<n;k++) {//删除从该节点出发的边,对应的终点的入度-1
if(map[j][k]==1) {
indegree[k]--;
}
}
break;
}
}
}
}
}
210. 课程排序 II
在原有基础上,要求输出一个合法的课程顺序;如果不能修满所有的课,则输出一个空的数组。
public class Solution {
public int[] findOrder(int numCourses, int[][] prerequisites) {
int[] empty = new int[0];
if(numCourses==0) return empty;
int edge=prerequisites.length;
if(edge==0) {
empty = new int[numCourses];
for(int i=0;i<numCourses;i++) empty[i]=i;
return empty;
}
int[][] map=new int[numCourses][numCourses];
int[] indegree=new int[numCourses];
res=new int[numCourses];
for(int i=0;i<edge;i++) {
int a=prerequisites[i][0];
int b=prerequisites[i][1];
if(map[b][a]==0) {
map[b][a]=1;
indegree[a]++;
}
}
toposort(map,indegree,numCourses);
if(count!=numCourses) return empty;
return res;
}
int count=0;
int[] res;
int num=0;
void toposort(int map[][],int indegree[],int n) {
int i,j,k;
for(i=0;i<n;i++) { //遍历n次
for(j=0;j<n;j++) {//找出入度为0的节点
if(indegree[j]==0) {
indegree[j]--;
count++;
res[num++]=j;
for(k=0;k<n;k++) {//删除从该节点出发的边,对应的终点的入度-1
if(map[j][k]==1) {
indegree[k]--;
}
}
break;
}
}
}
}
}