LeetCode 207. 课程表 【拓扑排序】

这篇博客探讨了一个利用拓扑排序算法解决课程先决条件的问题。在给定课程数量和它们的依赖关系后,算法判断是否有可能完成所有课程的学习。通过遍历依赖关系并使用队列进行拓扑排序,可以有效地检测是否存在循环依赖,从而确定课程是否能按顺序完成。这种方法对于优化学习路径和理解复杂依赖关系具有重要意义。

你这个学期必须选修 numCourse 门课程,记为 0 到 numCourse-1 。

在选修某些课程之前需要一些先修课程。 例如,想要学习课程 0 ,你需要先完成课程 1 ,我们用一个匹配来表示他们:[0,1]

给定课程总量以及它们的先决条件,请你判断是否可能完成所有课程的学习?

示例 1:

输入: 2, [[1,0]]
输出: true
解释: 总共有 2 门课程。学习课程 1 之前,你需要完成课程 0。所以这是可能的。

示例 2:

输入: 2, [[1,0],[0,1]]
输出: false
解释: 总共有 2 门课程。学习课程 1 之前,你需要先完成​课程 0;并且学习课程 0 之前,你还应先完成课程 1。这是不可能的。

提示:

输入的先决条件是由 边缘列表 表示的图形,而不是 邻接矩阵 。详情请参见图的表示法。
你可以假定输入的先决条件中没有重复的边。
1 <= numCourses <= 10^5

把所有入度为零的点添加进队列里,然后删除其边。若该边连接的另一个点入度为零,将其添加进队列。

class Solution {
public:
    static const int maxn = 1e5 + 10;
    int rd[maxn];
    vector<int>v[maxn];
    bool vis[maxn] = {0};
    bool canFinish(int numCourses, vector<vector<int>>& prerequisites) {
        for(int i = 0; i < prerequisites.size(); i++) {
            vector<int>edg = prerequisites[i];
            for(int j = 1; j < edg.size(); j++) {
                v[edg[j]].push_back(edg[0]);
            }
            rd[edg[0]]++;
        }
        queue<int>que;
        for(int i = 0; i < prerequisites.size(); i++) {
            vector<int>e = prerequisites[i];
            for(int j = 0; j < e.size(); j++) {
                int x = prerequisites[i][j];
            if(rd[x] ==  0 && vis[x] == false) que.push(x), vis[x] = true;
            }
            
        }
        while(!que.empty()) {
            int x = que.front();
            que.pop();
            for(int i = 0; i < v[x].size(); i++) {
                rd[v[x][i]]--;
                if(rd[v[x][i]] == 0)    que.push(v[x][i]);
            }
        }
        for(int i = 0; i < prerequisites.size(); i++) {
            if(rd[prerequisites[i][0]] != 0)
                return false;
        }
        return true;
    }
};

明出处。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值