1.题目描述
一道拓扑排序算法的应用题
There are a total of n courses you have to take, labeled from 0 to n - 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, return the >ordering of courses you should take to finish all courses.
There may be multiple correct orders, you just need to return one of them. >If it is impossible to finish all courses, return an empty array.
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 the correct course order is [0,1]4, [[1,0],[2,0],[3,1],[3,2]]
There are a total of 4 courses to take. To take course 3 you should have >finished both courses 1 and 2. Both courses 1 and 2 should be taken after >you finished course 0. So one correct course order is [0,1,2,3]. Another >correct ordering is[0,2,1,3].
2. 算法及代码
因为给定发关于边的向量不好操作,将vector转换成矩阵表示的邻接表。此外,主要采用DFS的思想,何时进队,何时出队,维护每一个节点的入度来考虑何时进队。
class Solution {
public:
vector<int> findOrder(int n, vector<pair<int, int> >& edges) {
vector<int> res, blank(0);
queue<int> tmp;
int inDegree[n];
bool G[n][n];
//转成邻接表的形式
for(int i = 0; i < n; i++) {
for(int j = 0; j < n; j++) {
G[i][j] = false;
}
}
for(int i = 0; i < n; i++) {
inDegree[i] = 0;
}
//转成邻接表的形式 ,记录入度
for(int k = 0; k < edges.size(); k++) {
inDegree[edges[k].second]++;
G[edges[k].first][edges[k].second] = true;
}
//入度为0,找到起点
for(int k = 0; k < n; k++) {
if(inDegree[k] == 0) {
tmp.push(k);
}
}
//找不到起点,存在环路
if(tmp.size() == 0)
return blank;
while(!tmp.empty()) {
int node = tmp.front();
tmp.pop();
for(int i = 0; i < n; i++) {
if(G[node][i]) {
inDegree[i]--; //入度为0时入队
if(inDegree[i] <= 0) {
tmp.push(i);
}
}
}
res.push_back(node);
}
// 内部有环路
if(res.size() != n) {
return blank;
}
reverse(res.begin(),res.end());
return res;
}
};