拓扑排序的题目。之前写了一个简单的做法,使用n*n的矩阵来保存图。时间复杂度是O(n^2)
改用邻接表来描述图。同时使用一个数组来记录每个结点的入度。初始化都为零。依次读入边,将边加入邻接表并将记录结点入度数组对应计数加一
读入完成后使用一个队列来记录所有入度为零的结点等待输出。
每次从队列中弹出一个结点,并扫描其邻接表所有邻接结点,将所有邻接结点的入度减一,如果入度为零了,将其加入到队列中。
循环处理队列,直到队列为空。结束循环后判断是否输出序列长度是否为所有结点的个数。若是,则有拓扑排序,若不是,则没有。代码如下:
struct node
{
int val;
node *next;
node(int _val = 0) :val(_val), next(NULL){}
};
class Solution {
public:
vector<int> findOrder(int numCourses, vector<pair<int, int>>& prerequisites) {
node* point2;
point2 = new node[numCourses];
queue<int> waitOutCourse;
int *privCourse = new int[numCourses];
memset(privCourse, 0, sizeof(int)*numCourses);
vector<int> result;
for (int i = 0; i < prerequisites.size(); ++i)
{
privCourse[prerequisites[i].first]++;
node *p = &point2[prerequisites[i].second];
while (p->next != NULL)
p = p->next;
p->next = new node(prerequisites[i].first);
}
for (int i = 0; i < numCourses;++i)
if (privCourse[i] == 0)
waitOutCourse.push(i);
while (!waitOutCourse.empty())
{
int cno = waitOutCourse.front();
waitOutCourse.pop();
result.push_back(cno);
node *p = point2[cno].next;
while (p != NULL)
{
--privCourse[p->val];
if (privCourse[p->val] == 0)
waitOutCourse.push(p->val);
node *q = p->next;
delete p;
p = q;
}
}
delete []point2;
delete []privCourse;
if (result.size() == numCourses) return result;
else return vector<int>();
}
};