import java.util.*; public class Solution { // 成环即返回false //存储有向图 public ArrayList<ArrayList<Integer>> lists; //节点的状态 0:从未访问过 1:正在访问搜索中 2:访问结束 public int[] visit; //标记是否成环,res为false就是成环了 public boolean res = true; public boolean canFinish (int numProject, ArrayList<ArrayList<Integer>> groups) { // write code here //初始化操作 lists = new ArrayList<>(); visit = new int[numProject]; for(int i = 0;i < numProject;i ++) { lists.add(new ArrayList<Integer>()); } //先完成的指向后完成(可能会指向多个后完成的,统统add) for(ArrayList<Integer> list:groups) { lists.get(list.get(1)).add(list.get(0)); } for(int i = 0;i < numProject;i ++) { //成环啦,跳出循环 if(!res) break; //遍历到一个没有被搜索过的节点 if(visit[i] == 0) func(i); } return res; } public void func(int index) { visit[index] = 1; //标记成正在搜索中 ArrayList<Integer> list = lists.get(index); //获取到该节点所有指向的节点(该项目需要在被指向的项目们之前完成) for(int k : list) { //遍历到一个没有被搜索过的节点,深度遍历 if(visit[k] == 0) { func(k); //成环啦,返回 if(!res) return; }else if(visit[k] == 1) { //正在搜索的过程中搜索到另一个正在搜索状态的节点,成环 res = false;//置为false,返回 return; } } //该节点的状态为搜索已完成 visit[index] = 2; } }