[LeetCode][210] Course Schedule II

[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;
    }
};

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值