您的位置:首页 > 其它

Leetcode解题笔记 207.Course Schedule [Medium] 拓扑排序

2017-09-25 11:31 585 查看

解题思路

这个星期算法课学了拓扑排序,所以就找了道关于拓扑排序的题来做,其实核心思想就是找
DAG(有向无环图)
,算法的思想就是通过bfs不断去削减节点,并寻找入度为0的点,最后判断所有点是否都变为入度为0的点。具体算法如下:

1. 用一个队列维护所有入度为0的节点,每次弹出一个节点v,查看从v可达的所有节点u;

2. 将u的入读减一,若u的入度此时为0, 则将u加入队列。

3. 在队列为空时,检查所有节点的入度,若所有节点入度都为0, 则存在这样的一个拓扑排序 —— 有向图中不存在环。

例子

例如对于
3,[[1, 0], [2, 0], [1, 2]]
,如图



算法第一步,将入度为0的点去掉,变化如下:



重复该部,最后所有入度变为0,该图是
DAG


而对于有环的图,如图:



由于不存在入度为0的点,所以无法找到一个可以入队列的点,所以无法削减。

代码实现

bool canFinish(int numCourses, vector<pair<int, int>>& prerequisites) {
vector<int> inOrder(numCourses, 0); //用于记录所有顶点的入度数
vector<vector<int>> map(numCourses); //用vector模拟的邻接链表
for (int i = 0; i < prerequisites.size(); i++) {
int priority = prerequisites[i].second;
int notPriority = prerequisites[i].first;
inOrder[notPriority]++; //需等待优先节点执行的非优先节点入度+1
map[priority].push_back(notPriority); //生成邻接链表
}

queue<int> q_BFS;
for (int i = 0; i < numCourses; i++) {
if (inOrder[i] == 0) q_BFS.push(i);
}

int count = q_BFS.size(); // 记录当前入度为0的点的数目

while(!q_BFS.empty()) {
for (int i = 0; i < map[q_BFS.front()].size(); i++) {
int check = --inOrder[map[q_BFS.front()][i]];
// 若入度削减为0成为root点,则加入队列。
if (check == 0) {
count++;
q_BFS.push(map[q_BFS.front()][i]);
}
}
q_BFS.pop();
}

return count == numCourses;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  leetcode