[LeetCode][210] Course Schedule II
抽象:给定一个无向图,判定是否有环。
使用拓朴排序(实质是dfs)
/*
* @lc app=leetcode id=210 lang=cpp
*
* [210] Course Schedule II
*
* https://leetcode.com/problems/course-schedule-ii/description/
*
* algorithms
* Medium (32.54%)
* Total Accepted: 117.8K
* Total Submissions: 361.9K
* Testcase Example: '2\n[[1,0]]'
*
* 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.
*
* Example 1:
*
*
* Input: 2, [[1,0]]
* Output: [0,1]
* Explanation: 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] .
*
* Example 2:
*
*
* Input: 4, [[1,0],[2,0],[3,1],[3,2]]
* Output: [0,1,2,3] or [0,2,1,3]
* Explanation: 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] .
*
* Note:
*
*
* The input prerequisites is a graph represented by a list of edges, not
* adjacency matrices. Read more about how a graph is represented.
* You may assume that there are no duplicate edges in the input
* prerequisites.
*
*
*/
class Solution
{
public:
vector<int> findOrder(int numCourses, vector<pair<int, int>> &prerequisites)
{
//因为是1到n顺序所以不需要使用Hash
vector<vector<int>> graph(numCourses);
for (const auto &p : prerequisites)
{
graph[p.second].push_back(p.first);
}
vector<int> v(numCourses, 0);
vector<int> res;
//0 not visit 1 visiting 2 visited
for (int i = 0; i < numCourses; i++)
{
if (dfs(i, graph, v, res))
{
return {};
}
}
std::reverse(res.begin(), res.end());
return res;
}
//如果返回true是代表有环
bool dfs(int cur, vector<vector<int>> &graph, vector<int> &v, vector<int> &res)
{
//正在返回 再次遇到说明是有环
if (v[cur] == 1)
{
return true;
}
if (v[cur] == 2)
{
return false;
}
v[cur] = 1;
//访问它的下一个节点
for (const int t : graph[cur])
{
//只有有true就会进去这个if语句从而导致退出是是返回true的
if (dfs(t, graph, v, res))
{
return true;
}
}
v[cur] = 2;
res.push_back(cur);
//当前访问无环
return false;
}
};