课程表(LeetCode/判断有向图是否有环/拓扑排序/dfs)

CSP认证的第三题遇到了判断环的问题,当时用了dfs求解,样例跑对了,可是还是拿不到后面50分,有可能是找环的逻辑不太对。

因此上LeetCode刷了这道判断有向图是否有环的题。

原题链接

题目描述

你这个学期必须选修 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. 输入的先决条件是由 边缘列表 表示的图形,而不是 邻接矩阵 。详情请参见图的表示法。
  2. 你可以假定输入的先决条件中没有重复的边。
  3. 1 <= numCourses <= 10^5

思路

这道题我们需要将每一门课看成一个节点,如果想要学习课程 A 之前必须完成课程B,那么我们从B到A连接一条有向边,如果最终图里出现了环,就意味着两个课程是彼此的先决条件,显然不可能。

可以使用拓扑排序和dfs深度优先遍历两种方法解决:

(1)拓扑排序

拓扑排序:给定一个包含 n 个节点的有向图 G,我们给出它的节点编号的一种排列,如果满足:对于图 G 中的任意一条有向边 (u, v),u 在排列中都出现在 v 的前面。

根据上述的定义,我们可以得出两个结论:

在这里插入图片描述
因此我们只需要可以进行以下算法流程

  1. 将所有入度为0的结点入队列
  2. 当队列不为空时,取出栈顶元素,出队,将被其指向的结点的入度减为0,如果有某个结点的入度也变为0,则将该结点入队
  3. 重复步骤2,直到队列为空
  4. 判断是否仍有入度不为0的结点,若有则存在环,若无则不存在环

需要注意的是这道题一开始是保存边,而不是以邻接表或者邻接矩阵的形式保存,因此要自行转换一下。

代码如下:

class Solution {
   
public:
    bool canFinish(int numCourses, vector<vector<int>>& prerequisites) {
   
        vector<vector<int> > graph(numCourses);//邻接表
        vector<int> 
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值