问题分析
典型的有向图,判断是否存在回路问题。这里我使用的是Kaha算法。但是时间复杂度,空间负责度都过高,可以看出这里我存储时间负责和空间复杂度都为O(n^2),其问题在于如果是完全图他没问题,但是针对稀疏图则效率低下。
较优答案采用的是DFS的方式,通过从一个节点出发判断是否会再到达已经到达过的节点,来解决问题。后面的代码是我直接从以提交的答案上摘抄的。
class Solution {
public:
bool canFinish(int numCourses, vector<vector<int>>& prerequisites) {
vector<vector<int>> graph(numCourses, vector<int>(numCourses + 1, -1));
vector<int> finishCourses;
int requCount = 0;
for(auto &course : graph)
course[numCourses] = 0;
for(auto requires : prerequisites){
graph[requires[0]][requires[1]] = 1;
graph[requires[0]][numCourses]++;
requCount++;
}
for(int i = 0; i < numCourses; i++)
if(graph[i][numCourses] == 0){
finishCourses.push_back(i);
}
while(!finishCourses.empty()){
int finCour = finishCourses.back();
finishCourses.pop_back();
for(int i = 0;i < numCourses; i++){
if(graph[i][finCour] != -1){
graph[i][numCourses]--;
requCount--;
graph[i][finCour] = -1;
if(graph[i][numCourses] == 0)
finishCourses.push_back(i);
}
}
if(requCount == 0) return true;
}
return requCount == 0;
}
};
class Solution {
public:
bool canFinish(int numCourses, vector<vector<int>>& prerequisites) {
unordered_map<int,vector<int>> table;
vector<int> visited(numCourses,0);
bool ret;
int j;
for(int i=0;i<prerequisites.size();i++) {
table[prerequisites[i][1]].push_back(prerequisites[i][0]);
}
for(int i=0;i<numCourses;i++) {
if(!visited[i]) {
//visited[i] = -1;
ret = dfs(table,visited,i);
if(!ret)
return false;
}
//visited[i] = 1;
}
return true;
}
bool dfs(unordered_map<int,vector<int>>& table, vector<int>& visited, int source) {
int child;
bool ret;
if(visited[source]==-1)
return false;
if(visited[source]==1)
return true;
visited[source] = -1; // 对于现在正在遍历的节点标记为 -1
for(int k=0;k<table[source].size();k++) {
child = table[source][k];
ret = dfs(table,visited,child);
if(!ret)
return false;
}
visited[source] = 1; // 已经完整遍历的节点标记为1,防止其他节点对其再进行DFS,节省时间
return true;
}
};