LeetCode207 Course Schedule
问题描述
here 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.
问题分析
这道题的提示也说到了,这道题就是判断有向图是否存在环路。那么还是图的那一套,广度优先和深度优先。在这里我选择了深度优先,为了提高算法的效率要要确定哪些是已经遍历过的节点,从而及时的剪枝。
代码如下
Java代码
public boolean canFinish(int numCourses, int[][] prerequisites) {
//初始化List
List<List<Integer>> list = new ArrayList<>(numCourses);
for (int i = 0; i <numCourses ; i++) {
list.add(new ArrayList<>());
}
//给每个节点添加子节点
for (int[] array: prerequisites
) {
list.get(array[0]).add(array[1]);
}
//初始化全局已访问节点数组
boolean[] visitedPre = new boolean[numCourses];
for (int i = 0; i < numCourses; i++) {
//当全局未访问,对该节点的路径进行递归,如果错误,返回false,否则继续
if(!visitedPre[i]&&!help(i,list,new boolean[numCourses],visitedPre)) return false;
}
//全部路径搜寻完毕,没有环状路径
return true;
}
boolean help(int from,List<List<Integer>> lists,boolean[] visited,boolean[] visitedPre){
//如果当前节点全局未访问
if(!visitedPre[from]){
//当前节点设为该路径的未访问
visited[from]=true;
//遍历子节点
for (int nextFrom: lists.get(from)){
//如果该该节点出现在该路径重复出现,说明出环,返回false
if(visited[nextFrom]||!visitedPre[from]&&!help(nextFrom,lists,visited,visitedPre))
return false;
}
//将路径数组恢复
visited[from] = false;
//将该节点设为全局已访问
visitedPre[from]=true;
}
return true;
}
LeetCode学习笔记持续更新
GitHub地址 https://github.com/yanqinghe/leetcode
CSDN博客地址 http://blog.csdn.net/yanqinghe123/article/category/7176678