210. Course Schedule II
2016-06-25 21:47
218 查看
There are a total of n courses you have to take, labeled from
Some courses may have prerequisites, for example to take course 0 you have to first take course 1, which is expressed as a pair:
Given the total number of courses and a list of prerequisite pairs, return the ordering of courses you should take to finish all courses.
There may be multiple correct orders, you just need to return one of them. If it is impossible to finish all courses, return an empty array.
For example:
There are a total of 2 courses to take. To take course 1 you should have finished course 0. So the correct course order is
There are a total of 4 courses to take. To take course 3 you should have finished both courses 1 and 2. Both courses 1 and 2 should be taken after you finished course 0. So one correct course order is
Another correct ordering is
Note:
The input prerequisites is a graph represented by a list of edges, not adjacency matrices. Read more about how
a graph is represented.
这是一个有向图的拓扑排序问题。首先要检测是否存在环,如果存在环是不会有拓扑排序的。
拓扑排序就是dfs访问各个顶点的”逆后序“顺序,后序是指dfs调用即将结束时将顶点加入集合,“逆”即集合选用栈
boolean hascycle = false;
boolean[] onstack, used;
Stack<Integer> reversepost;
public int[] findOrder(int numCourses, int[][] prerequisites)
{
reversepost=new Stack<>();
int[] arr={};
if(canFinish(numCourses, prerequisites))
{
arr=new int[reversepost.size()];
int cnt=0;
while(!reversepost.isEmpty())
arr[cnt++]=reversepost.pop();
}
return arr;
}
public boolean canFinish(int numCourses, int[][] prerequisites)
{
if (numCourses < 1)
return true;
int m = prerequisites.length;
ArrayList<Integer>[] adjlist = new ArrayList[numCourses];
for (int i = 0; i < numCourses; i++)
adjlist[i] = new ArrayList<>();
for (int i = 0; i < m; i++)
adjlist[prerequisites[i][1]].add(prerequisites[i][0]);
onstack = new boolean[numCourses];
used = new boolean[numCourses];
for (int i = 0; i < numCourses; i++)
if (!used[i])
dfs(i, adjlist);
return !hascycle;
}
private void dfs(int i, ArrayList<Integer>[] adjlist)
{
used[i] = true;
onstack[i] = true;
for (int a : adjlist[i])
if (hascycle)
return;
else if (!used[a])
dfs(a, adjlist);
else if (onstack[a])
{
hascycle = true;
return;
}
onstack[i] = false;
reversepost.push(i);
}
0to
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, return the ordering of courses you should take to finish all courses.
There may be multiple correct orders, you just need to return one of them. If it is impossible to finish all courses, return an empty array.
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 the correct course order is
[0,1]
4, [[1,0],[2,0],[3,1],[3,2]]
There are a total of 4 courses to take. To take course 3 you should have finished both courses 1 and 2. Both courses 1 and 2 should be taken after you finished course 0. So one correct course order is
[0,1,2,3].
Another correct ordering is
[0,2,1,3].
Note:
The input prerequisites is a graph represented by a list of edges, not adjacency matrices. Read more about how
a graph is represented.
这是一个有向图的拓扑排序问题。首先要检测是否存在环,如果存在环是不会有拓扑排序的。
拓扑排序就是dfs访问各个顶点的”逆后序“顺序,后序是指dfs调用即将结束时将顶点加入集合,“逆”即集合选用栈
boolean hascycle = false;
boolean[] onstack, used;
Stack<Integer> reversepost;
public int[] findOrder(int numCourses, int[][] prerequisites)
{
reversepost=new Stack<>();
int[] arr={};
if(canFinish(numCourses, prerequisites))
{
arr=new int[reversepost.size()];
int cnt=0;
while(!reversepost.isEmpty())
arr[cnt++]=reversepost.pop();
}
return arr;
}
public boolean canFinish(int numCourses, int[][] prerequisites)
{
if (numCourses < 1)
return true;
int m = prerequisites.length;
ArrayList<Integer>[] adjlist = new ArrayList[numCourses];
for (int i = 0; i < numCourses; i++)
adjlist[i] = new ArrayList<>();
for (int i = 0; i < m; i++)
adjlist[prerequisites[i][1]].add(prerequisites[i][0]);
onstack = new boolean[numCourses];
used = new boolean[numCourses];
for (int i = 0; i < numCourses; i++)
if (!used[i])
dfs(i, adjlist);
return !hascycle;
}
private void dfs(int i, ArrayList<Integer>[] adjlist)
{
used[i] = true;
onstack[i] = true;
for (int a : adjlist[i])
if (hascycle)
return;
else if (!used[a])
dfs(a, adjlist);
else if (onstack[a])
{
hascycle = true;
return;
}
onstack[i] = false;
reversepost.push(i);
}
相关文章推荐
- bzoj2698: 染色
- 使用注解标注Servlet
- Android_GET与POST_面向过程
- hdu4882ZCC Loves Codefires【贪心】2014多校联合
- 图书管理系统JAVA语言
- 正则表达式
- 随机行读取文件
- OJ网站小结
- substr,substring,slice 的区别
- Freezer - OpenStack备份项目简介
- 通过异步任务LoaderManager加载Cursor游标
- 目标跟踪算法的分类(二)
- 自制编译器---c++实现词法分析器
- 计算机的硬件组成
- spark入门
- Word文档目录自动生成和页码设置
- IOS Dev Intro - FBO
- linux下安装svn
- 委托
- Java并发编程:volatile关键字解析