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:

  1. The input prerequisites is a graph represented by a list of edges, not adjacency matrices. Read more about how a graph is represented.
  2. You may assume that there are no duplicate edges in the input prerequisites。

主要考察的图的遍历。

自己写的都超时了,说明还是有很多问题。

1、暴力算法,结果超时。

public class Solution {
    public boolean canFinish(int numCourses, int[][] prerequisites) {
        
        int[][] num = new int[numCourses][numCourses];
        for (int i = 0; i < prerequisites.length; i++){
            num[prerequisites[i][0]][prerequisites[i][1]] = 1;
        }
        int[] finish = new int[numCourses];
        boolean flag = false;
        while (true){
            flag = false;
            for (int i = 0; i < numCourses; i++){
                for (int j = 0; j < numCourses; j++){
                    if (num[i][j] == 1){
                        break;
                    } else if (j == numCourses - 1 && finish[i] == 0){
                        finish[i] = 1;
                        isfinish(num, i);
                        flag = true;
                    }
                }
            }
            if (flag == false){
                for (int i = 0; i < numCourses; i++){
                    if (finish[i] == 0)
                        break;
                    else if (i == numCourses - 1)
                        return true;
                }
                return false;
            }
        }
    }
    public void isfinish(int[][] num, int pos){
        for (int i = 0; i < num.length; i++){
            num[i][pos] = 0;
        }
    }
}

 

 

2、优化一下,然而还是超时。

public class Solution {
    public boolean canFinish(int numCourses, int[][] prerequisites) {
        
        int[][] num = new int[numCourses][numCourses];
        for (int i = 0; i < prerequisites.length; i++){
            if (num[prerequisites[i][1]][prerequisites[i][0]] == 1){
                return false;
            }
            num[prerequisites[i][0]][prerequisites[i][1]] = 1;
            for (int j = 0; j < numCourses; j++){
                /*
                k = prerequisites[i][1]之前需要完成的工作(也就是num[k][j] == 1),都需要完成
                num[num[prerequisites[i][0]][j] = 1;
                */
                if (num[prerequisites[i][1]][j] == 1){
                    num[prerequisites[i][0]][j] = 1;
                }
                /*
                需要先完成k = prerequisites[i][0]才能完成的工作(num[j][k] == 1),也要完成 num[j][prerequisites[i][1]] = 1;
                */
                if (num[j][prerequisites[i][0]] == 1){
                    num[j][prerequisites[i][1]] = 1;
                }
            }
            
        }
        return true;
    }
    
}

 

3、DFS(参考discuss)

public class Solution {
    public boolean canFinish(int numCourses, int[][] prerequisites) {
        
        ArrayList[] list = new ArrayList[numCourses];
        for (int i = 0; i < numCourses; i++){
            list[i] = new ArrayList<Integer>();
        }
        for (int i = 0; i < prerequisites.length; i++){
            list[prerequisites[i][1]].add(prerequisites[i][0]);
        }
        boolean[] visit = new boolean[numCourses];
        for (int i = 0; i < numCourses; i++){
            if (!dfs(list, visit, i)){
                return false;
            }
        }
        return true;
    }
    
    public boolean dfs(ArrayList[] list, boolean[] visit, int pos){
        if (visit[pos]){
            return false;
        } else {
            visit[pos] = true;
        }
        for (int i = 0; i < list[pos].size(); i++){
            if (!dfs(list, visit, (int) list[pos].get(i))){
                return false;
            }
       list[pos].remove(i); } visit[pos]
= false; return true; } }

 

 

 

4、BFS

public class Solution {
    public boolean canFinish(int numCourses, int[][] prerequisites) {

        List<Integer>[] adj = new List[numCourses];    
        for(int i = 0; i < numCourses; i++)
            adj[i] = new ArrayList<Integer>();
        int[] indegree = new int[numCourses];          
        Queue<Integer> readyCourses = new LinkedList(); 
        int finishCount = 0;                        
        for (int i = 0; i < prerequisites.length; i++)  
        {
            int curCourse = prerequisites[i][0];        
            int preCourse = prerequisites[i][1];        
            adj[preCourse].add(curCourse);
            indegree[curCourse]++;
        }
        for (int i = 0; i < numCourses; i++) 
        {
            if (indegree[i] == 0) 
                readyCourses.offer(i);           
        }
        while (!readyCourses.isEmpty()) 
        {
            int course = readyCourses.poll();        // finish
            finishCount++;
            for (int nextCourse : adj[course]) 
            {
                indegree[nextCourse]--;
                if (indegree[nextCourse] == 0)    
                    readyCourses.offer(nextCourse);  // ready
            }
        }
        return finishCount == numCourses;
    }
}