leetcode —— 207. 课程表

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

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

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

示例 1:

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

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/course-schedule
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
——————————————
解题思路:建立两个列表,列表in_dot是计算每个节点的入度,意思是要学习当前课程,需要提前学习的课程的选项有几个。如果课程列表[2,3,4]是学习课程1的前提选项,意思就是学习了课程2,或者学习了课程3,或者学习了课程4才能学习课程1。这样课程1的入度就是3。

第二个列表dicts是指某个课程是其它课程学习的前提。比如dicts[1]=[2,3,4]意思就是要学习课程2,或者学习课程3,或者学习课程4,首先需要先学习课程2。

如果想要能够学完课程,所构造的有向图中必须不存在一个包含所有节点的环,如果存在包含所有节点的环则每个课程都有前提要求课程,这样是肯定不能满足题目要求。

我们先从in_dot列表中寻找入度为0的课程节点,因为这些课程是不需要先修课程的,基于这些课程使用广度优先遍历。

每遍历一个没有入度的节点,则将与该节点出度相连接的节点课程的入度减一,如果这些减一的课程的入度变为零,则又可以重复上面的循环。

每当遍历出队一个没有入度的课程,则要学习的课程数减一。如果最后队列为空时,需要学习的课程数为0,则证明可以学习完所有的课程。

具体Python代码如下:

class Solution:
    def canFinish(self, numCourses: int, prerequisites: List[List[int]]) -> bool:
        in_dot = [0 for _ in range(numCourses)]  # 每个课程的入度
        dicts = [[] for _ in range(numCourses)]  # 每个课程的出度课程列表

        for end,begin in prerequisites:  # begin是先修课程,end是要学课程
            in_dot[end] += 1  # 要学课程的入度
            dicts[begin].append(end)  # 先修课程的出度课程
            
        queue = collections.deque()
        for i in range(len(in_dot)):  # 找到初始入度为0的课程
            if in_dot[i]==0:
                queue.append(i)

        while queue:    # 遍历入度为0的课程
            num = queue.popleft()
            numCourses -= 1    # 入度为0的课程不需要先修课程,直接使课程数减1
            for index in dicts[num]:   # 遍历入度为零的课程的出度课程
                in_dot[index] -= 1  # 去掉入度为零的课程,则对应的出度课程的入度数减一
                if in_dot[index] == 0:    # 如果入度为零,则变为不用先修的课程,入队
                    queue.append(index)
        return numCourses==0
发布了320 篇原创文章 · 获赞 21 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/qq_37388085/article/details/105272707