解法一 DFS
思路
Using topological sort to solve this question. Topological sort is a linear order of vertices which for every edge uv from u to v, u always comes before v. As long as there is a cycle detected, which means there exists an edge uv, v comes before u, so it is not a topological sort.
To actual solve this problem, we may first construct a graph for the prerequisite courses. We may use ArrayList<Integer>[]
array to build the graph. For each course, we add all the illegible courses we can take after it.
Then for each course, we do a dfs to search the following courses. We lable each of the vertex we currently visit in this round as visiting. If the vertex we currently visit has been labled as visiting, then there will be a cycle. If a vertex has no out-going edge, we label it as visited. The exit for the dfs recursion is if we reach a vertex which is visiting, we return true cuz we find a cycle; if the vertex is visited, we return false because it has no out going edges.
程式碼
class Solution {
public boolean canFinish(int numCourses, int[][] prerequisites) {
// Construct a graph for course
ArrayList<Integer>[] graph = new ArrayList[numCourses];
for (int i = 0; i < numCourses; i++) {
graph[i] = new ArrayList<Integer>(); // To add all illegible courses in.
}
for (int[] pre : prerequisites) {
graph[pre[1]].add(pre[0]);
}
int[] visit = new int[numCourses];
for (int i = 0; i <numCourses; i++) {
if (hasCycle(i, visit, graph)) return false;
}
return true;
}
// DFS to detect a cycle
// 1 = visiting; 2 = visited
private boolean hasCycle(int index, int[] visit, ArrayList<Integer>[] graph) {
if (visit[index] == 1) {
return true;
} else if (visit[index] == 2) {
return false;
}
visit[index] = 1;
for (int i = 0; i < graph[index].size(); i++) {
int neighbor = graph[index].get(i);
if (hasCycle(neighbor, visit, graph)) {
return true;
}
}
visit[index] = 2;
return false;
}
}
複雜度分析
- 時間複雜度
The time complexity for topological sort is O(|V| + |E|). - 空間複雜度
O(|V||E|)?
解法二 BFS
思路
程式碼
複雜度分析
- 時間複雜度
- 最好情況
- 最壞情況
- 平均情況
- 空間複雜度