题:https://leetcode.com/problems/course-schedule/description/
题目
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?
Example 1:
Input: 2, [[1,0]]
Output: true
Explanation: There are a total of 2 courses to take.
To take course 1 you should have finished course 0. So it is possible.
Example 2:
Input: 2, [[1,0],[0,1]]
Output: false
Explanation: 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.
- You may assume that there are no duplicate edges in the input prerequisites.
题目大意
判断给定的 图是否 存在环。
思路
方法一 拓扑排序
找到图中入度为1的节点,删去 该点以及该点的出边。
重复上述操作。
若所有点 都 度为1,那么该图为五环图。
class Solution {
public boolean canFinish(int numCourses, int[][] prerequisites) {
List<Integer>[] graph = new List[numCourses];
for(int i = 0 ;i < numCourses;i++){
graph[i] = new ArrayList<>();
}
int[] inDegree = new int[numCourses];
for(int i = 0; i < prerequisites.length;i++){
graph[prerequisites[i][1]].add(prerequisites[i][0]);
inDegree[prerequisites[i][0]]++;
}
Queue<Integer> quque = new LinkedList<>();
for(int i = 0; i < inDegree.length;i++){
if(inDegree[i] == 0)
quque.offer(i);
}
while(!quque.isEmpty()){
int curNode = quque.poll();
for(int i = 0;i < graph[curNode].size();i++)
if(--inDegree[graph[curNode].get(i)] == 0)
quque.offer(graph[curNode].get(i));
}
for(int i = 0;i < inDegree.length ; i++)
if(inDegree[i] != 0 )
return false;
return true;
}
}
上述方法的 小改进,统计 删除的点。若删除的点 等于 图中所有的点,那么该图为无环图。
方法二 DFS 探索法
从一个点 DFS探索,若本次 探索过程中,发现当前点已经被探索了。那么该图必有环。
若当前点,在以前的探索过程中已经探索了,那么 探索的为同一个连通分量,该分量比没有 环。
用BDFS ,将localMarked 标识为 当前的 探索的点。
class Solution {
public boolean canFinish(int numCourses, int[][] prerequisites) {
List<Integer>[] graph = new List[numCourses];
for(int i = 0;i<graph.length;i++)
graph[i] = new ArrayList<>();
for(int i = 0;i<prerequisites.length;i++){
graph[prerequisites[i][1]].add(prerequisites[i][0]);
}
boolean [] globalMarked = new boolean[numCourses];
boolean [] localMarked = new boolean[numCourses];
for(int i = 0 ;i < numCourses;i++)
if(hasCycle(globalMarked,localMarked,graph,i))
return false;
return true;
}
public boolean hasCycle(boolean[] globalMarked,boolean[] localMarked,List<Integer>[] graph,int curNode){
if(localMarked[curNode])
return true;
if(globalMarked[curNode])
return false;
localMarked[curNode] = true;
globalMarked[curNode] = true;
for(int nextNode:graph[curNode])
if(hasCycle(globalMarked,localMarked,graph,nextNode))
return true;
localMarked[curNode] = false;
return false;
}
}