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:
- 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、暴力算法,结果超时。
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; } }