题目:
There are a total of n courses you have to take, labeled from 0
ton - 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 abouthow a graph is represented.
先将给出的图表示方法转换为{起点: 终点列表}的表示方法,可用hashmap或vector表示。
然后判断是否有环,注意用visited[i] = -1 所做的优化。
C++版:
class Solution {
public:
bool canFinish(int numCourses, vector<pair<int, int>>& prerequisites) {
vector<vector<int>> relies(numCourses, vector<int>(0));
for(auto i : prerequisites) {
relies[i.first].push_back(i.second);
}
vector<int> visited(numCourses, 0);
for(int i = 0; i < numCourses; i++) {
if(testLoop(i, relies, visited))
return false;
}
return true;
}
bool testLoop(int i, vector<vector<int>>& relies, vector<int>& visited) {
if(visited[i] == 1) return true;
if(visited[i] == -1) return false;
visited[i] = 1;
for(auto j : relies[i]) {
if(testLoop(j, relies, visited))
return false;
}
visited[i] = -1;
return false;
}
};
Java版:
public class Solution {
public boolean canFinish(int numCourses, int[][] prerequisites) {
if(prerequisites.length == 0)
return true;
Map<Integer, ArrayList<Integer>> relies = new HashMap<>();
for(int i = 0; i < prerequisites.length; i++) {
if(relies.containsKey(prerequisites[i][0])) {
relies.get(prerequisites[i][0]).add(prerequisites[i][1]);
} else {
ArrayList<Integer> l = new ArrayList<>();
l.add(prerequisites[i][1]);
relies.put(prerequisites[i][0], l);
}
}
int[] visited = new int[numCourses];
for(int i = 0; i < numCourses; i++) {
if(testLoop(relies, i, visited))
return false;
}
return true;
}
boolean testLoop(Map<Integer, ArrayList<Integer>> relies, int i, int[] visited) {
if(visited[i] == 1) return true;
if(visited[i] == -1) return false;
visited[i] = 1;
if(relies.containsKey(i)) {
for(int j : relies.get(i)) {
if(testLoop(relies, j, visited))
return true;
}
}
visited[i] = -1;
return false;
}
}
Python版:
class Solution:
# @param {integer} numCourses
# @param {integer[][]} prerequisites
# @return {boolean}
def canFinish(self, numCourses, prerequisites):
if len(prerequisites) == 0:
return True
d = {}
for i in range(numCourses):
d[i] = []
for i in prerequisites:
d[i[0]].append(i[1])
visited = [0] * numCourses
for i in range(numCourses):
if self.testLoop(i, d, visited):
return False
return True
def testLoop(self, i, d, visited):
if visited[i] == 1:
return True
if visited[i] == -1:
return False
visited[i] = 1
for j in d[i]:
if self.testLoop(j, d, visited):
return True
visited[i] = -1
return False