【力扣刷题】(207. 课程表)记录

一、题目分析

(1)题目问题可以抽象为检测一个有向图是否存在环。若有,则 return False ;没有,则 return True
(2)对于一个有向图,我们可以一个一个地删除入度为零的节点,每删除一个,与其相连的有向线段当然也要跟着删除(即以该点为前序课程的点入度-1)。容易分析得到,这个过程不会破坏图中的环(如果存在的话。环中每一个点的入度都不为零,所以不可能被删除。
因此,迭代这个过程,直到不存在入度为零的点。此时若图仍然存在(仍然存在点),则可判断有环的存在。
(3)现上述原理:
关于有向图的表示:鉴于题目所给的输入都是int型数据,所以可以直接用两个数组,一个一维数组,用来存放每个编号课程所代表的课程的 入度,其索引即为课程编号;另一个是二维数组,用来存放以该索引数字所代表的课程的后续课程。
由任意一个入度为0的点开始,遍历整个图,依次删除入度为0的点。遍历采用BFS算法或者DFS算法都可以。

二、题目解法及代码

2.1

这里采用BFS算法,参考这个高赞的答案,写的很棒,初始化变量就把我这个小白惊呆了。第一遍看从头懵到尾。第二天去看了一天的BFS和DFS算法(关于这个墙裂推荐B站UP主‘正月点灯笼’的教学视频,链接奉上。),从原理到实现,第三天才看明白,并且能够做一些小的改动了。比如答案中遍历用的是collections库中的deque双向队列。我也不是太熟悉,搜了搜,感觉还是用前一天先学的普通的queue就可以实现本问题。于是自己复现的时候直接用的是普通的数组了。
详细解释代码如下:

class Solution:
    def canFinish(self, numCourses: int, prerequisites: List[List[int]]) -> bool:
        #### Initialize the required variables
        indegress = [0 for _ in range(numCourses)] # 一维数组,存放入度数
        adjacency = [[]for _ in range(numCourses)] # 二维数组,存放后续课程
        queue = []  # 用来实现遍历的队列
        nums = numCourses # 记录图中剩余的节点

        ### Represent the graph
        for cour,pre in prerequisites:
            indegress[cour] += 1
            adjacency[pre].append(cour)
        
        ### Put the first batch of vertexes whoesindegrees is 0 into the queue
        for i in range(len(indegress)):
            if indegress[i] == 0: 
                queue.append(i)
        ### Traverse the entire graph, removing points with 0 indegree
        while queue:
            ver = queue.pop(0)  # 这里无所谓是pop(0)或者pop(),前者为BFS,后者为DFS算法。
            nums -= 1    # 遍历一个节点,节点数减一
            for i in adjacency[ver]:
                indegress[i] -= 1  # 对于遍历到并删除的入度为0的点,同时删除
                if not indegress[i] : queue.append(i)
        ### Returns True if the number of remaining vertexes is 0
        return not nums

另外对于输入的课程信息不是用int型的数据表示的,而是用str表示的话,indegressadjacency可以选择字典型数据来构造,同样分别是一维的和二维的。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值