解法
dfs和bfs
dfs
深度优先遍历,也就是没环的话继续尝试其他的节点,有环的话就层层返回false,大概的情况就是下面
以当前节点作为传入节点,然后遍历这个节点的全部相邻进入的节点, 有一个不符合条件,就返回false,遍历完了全部才返回true
在这里需要设置三个标志位,0,1,-1
0表示没有访问过
1表示当前的递归访问过了
-1表示其他的递归访问过了
public static boolean canFinish(int numCourses, int[][] prerequisites) { //0表示没有访问过,-1表示已经访问过 int[] flag = new int[numCourses]; ArrayList<ArrayList<Integer>> graph = new ArrayList<>(); //形成图 for (int i = 0; i < numCourses; i++) { graph.add(new ArrayList<>()); } for(int i=0;i<numCourses;i++) { if(!f(i,graph,flag)) return false; } return true; } //以p作为起点,是否有环 public static boolean f(int p, ArrayList<ArrayList<Integer>> graph, int[] flag) { //base case if(flag[p]==-1) return false;//自己的 if(flag[p]==1) return true;//其他的 flag[p]=-1; for(Integer e:graph.get(p)) { if(!f(e,graph,flag)) return false; } flag[p]=1; return true; }
需要注意的位置就是flag置为1和-1的时机
bfs
宽度优先遍历就是通过队列的参与,选择入度为0的入队,开始遍历相邻的节点,直到相邻的节点入度变成0了就可以入队了
```
/*
prerequisites 多维两列数组
第一列为被进入的
第二列为进入的
*/
public static boolean canFinish(int numCourses, int[][] prerequisites) {
int[] in=new int[numCourses];//入度表 ArrayList<ArrayList<Integer>> graph=new ArrayList<>();//图 LinkedList<Integer> queue=new LinkedList<>(); //初始化图 for(int i=0;i<numCourses;i++) { graph.add(new ArrayList<>()); } //形成图和入度表 for(int i=0;i<prerequisites.length;i++) { in[prerequisites[i][0]]++; graph.get(prerequisites[i][1]).add(prerequisites[i][0]); } for(int i=0;i<numCourses;i++) { if(in[i]==0) queue.addLast(i); } while(!queue.isEmpty()) { int temp=queue.pollFirst(); numCourses--; ArrayList<Integer> tempGraph=graph.get(temp); for(Integer e:tempGraph) { if(--in[e]==0) queue.addLast(e); } } return numCourses==0; }
``