問題分析
典型的有向圖,判斷是否存在迴路問題。這裏我使用的是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;
}
};