Leetcode May Challenge - 05/29: Course Schedule(Python)

题目描述

There are a total of numCourses courses you have to take, labeled from 0 to numCourses-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, is it possible for you to finish all courses?
Constraints:

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.
1 <= numCourses <= 10^5

例子

Example 1:

Input: numCourses = 2, prerequisites = [[1,0]]
Output: true
Explanation: There are a total of 2 courses to take. 
             To take course 1 you should have finished course 0. So it is possible.

Example 2:

Input: numCourses = 2, prerequisites = [[1,0],[0,1]]
Output: false
Explanation: There are a total of 2 courses to take. 
             To take course 1 you should have finished course 0, and to take course 0 you should
             also have finished course 1. So it is impossible.

解释

有一个课表prerequisites,里面是一个[i, j]的键值对,表示要上i这门课,必须先上j这门课。还有一个正整数numCourses,表示总共有多少门课。我们现在要求有没有一种上课的方法,让一个人能够上完所有的课。

思路 拓扑排序 BFS

如果我们把prerequisites这个列表想成一个有向图,则能够上完所有课的条件就是图中无环,即该图能够拓扑排序。因此这是一道典型的广度优先搜索(BFS)的应用。
首先我们构造有向图。我们让有向图的边从j指向i。构造图的方法不多赘述了,python中用字典很容易实现。
然后我们创建一个数组,数组中存储每一门课程当前条件下还需要多少个直接的prerequisites。即每个课程在有向图中的对应点的入度是多少。这个变量很关键。我们在后面BFS的过程中判断是否入队列就是依照这个数组里面的值。
最后我们维护一个队列。队列中放所有入度为0的点。具体实现中,我们首先把初始入度就为0的点放进去,然后对这些点在字典中去查找对应的value,把value对应的在数组中的值减1,如果此时值变为0,则放入队列。
同时我们用一个变量total来记录当前总共上了几门课。如果最后total的值和numCourses相等,则返回True。

代码

class Solution(object):
    def canFinish(self, numCourses, prerequisites):
        """
        :type numCourses: int
        :type prerequisites: List[List[int]]
        :rtype: bool
        """
        import collections
        graph = collections.defaultdict(list)
        numpre = [0] * numCourses
        
        for i, j in prerequisites:
            graph[j].append(i)
            numpre[i] += 1
        
        q = []
        for i in range(len(numpre)):
            if numpre[i] == 0:
                q.append(i)
        total = 0
        while q:
            cur = q.pop(0)
            total += 1
            for i in range(len(graph[cur])):
                numpre[graph[cur][i]] -= 1
                if not numpre[graph[cur][i]]:
                    q.append(graph[cur][i])
        return total == numCourses
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值