題目大意
給出n個課程,以及某些課程的預置課程,某課程的預置課程表示必須先參加預置課程後才能再參加該課程。判斷是否可以完成所有的課程。
輸入
n表示課程數,列表表示課程的預置課程:numCourses = 2, prerequisites = [[1,0]]
。
思路
可以抽象爲有向圖是否有環的問題,而該問題有兩種解決方法:
-
深度優先搜索判斷
搜索過程若遇到了之前訪問過的節點則表示有環
-
利用每個節點的入度判斷
將所有入度爲0的節點加入隊列,對隊列每個節點,刪除從其出發的所有邊,更新節點的入度,將新的入度爲0的節點加入隊列,直到發現 節點入度小於0 或者循環結束後 依舊存在入度不爲0的節點。
代碼
第二種方法的代碼。
typedef vector<vector<int>> vvi;
class Solution {
public:
bool canFinish(int numCourses, vector<vector<int>>& prerequisites) {
if (numCourses <= 1)
return true;
vector<int> indegrees(numCourses, 0);
vector<vector<int>> graph(numCourses);
for (auto tmpvec: prerequisites){
graph[tmpvec[1]].push_back(tmpvec[0]);
indegrees[tmpvec[0]]++;
}
queue<int> q;
for (int i = 0; i < numCourses; i++)
if (indegrees[i] == 0)
q.push(i);
if (q.empty() && numCourses > 1)
return false;
while(!q.empty()) {
int u = q.front();
q.pop();
for (int child: graph[u]) {
indegrees[child]--;
if (indegrees[child] == 0)
q.push(child);
else if (indegrees[child] < 0)
return false;
}
}
for (int i = 0; i < numCourses; i++)
if (indegrees[i] != 0)
return false;
return true;
}
};
總結
經典題目。