Course Schedule I
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.
Note:
The input prerequisites is a graph represented by a list of edges, not adjacency matrices. Read more about how a graph is represented.
思路:本題等同於圖裏找circle。 用DFS找circle。爲剪枝,找到circle,直接停止(用個全局變量)。起始把數組轉換成Hashmap便於DFS。
public class Solution {
public boolean findCircle = false;
public boolean canFinish(int numCourses, int[][] prerequisites) {
Map<Integer, List<Integer>> map = new HashMap<>();
for(int i=0; i<prerequisites.length; i++){
if(!map.containsKey(prerequisites[i][0])){
List<Integer> al = new ArrayList<>();
al.add(prerequisites[i][1]);
map.put(prerequisites[i][0],al);
}
else{
map.get(prerequisites[i][0]).add(prerequisites[i][1]);
}
}
boolean[] marked = new boolean[numCourses];
for(int i=0; i<numCourses; i++){
if(findCircle) break;
dfs(i,map,marked);
}
return !findCircle;
}
public void dfs(int n, Map<Integer, List<Integer>> map, boolean[] marked){
if(marked[n]){
findCircle=true;
return;
}
if(!map.containsKey(n) || findCircle) return;
List<Integer> al = map.get(n);
marked[n]=true;
for(int i=0; i<al.size(); i++){
if(findCircle) break;
dfs(al.get(i), map, marked);
}
marked[n]=false;
}
}
思路2: BFS
先得到每個節點入度的數組in[]和所有入度爲0的節點作爲起始點集,開始BFS遍歷,到一個點將其入度-1,如果入度爲0,將其放到起始點集中,最後如果起始點集中元素個數大於總節點個數,則有圈。
Course Schedule II: Return correct course order
BFS Topology Sort, use in-degree array.
public class Solution {
public int[] findOrder(int numCourses, int[][] prerequisites) {
Map<Integer, List<Integer>> forward = new HashMap<>();
int[] in = new int[numCourses];
ArrayList<Integer> roots = new ArrayList<>();
int[] result = new int[numCourses];
int count = numCourses-1;
//0. convert edge array into hashmap
for(int i=0; i<prerequisites.length; i++){
if(!forward.containsKey(prerequisites[i][0])){
List<Integer> al = new ArrayList<>();
al.add(prerequisites[i][1]);
forward.put(prerequisites[i][0],al);
}
else{
forward.get(prerequisites[i][0]).add(prerequisites[i][1]);
}
in[prerequisites[i][1]]++;
}
//1. find all root candidats
for(int i=0; i<numCourses; i++){
if(in[i]==0) roots.add(i);
}
//2. bfs for all roots
while(!roots.isEmpty()){
int root = roots.remove(0);
result[count] = root;
count--;
List<Integer> children = forward.get(root);
while(children!=null && !children.isEmpty()){
int child = children.remove(0);
in[child]--;
if(in[child]==0){
roots.add(child);
forward.remove(root);
}
}
}
for(int i=0; i<numCourses; i++){
if(in[i]>0) return new int[0];
}
return result;
}
}