解法
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;
}``

京公网安备 11010502036488号