Top 100 Linked Question 修炼------第207题

本文深入探讨了课程调度问题,通过构建有向图并利用拓扑排序或深度优先搜索(DFS)来判断一组课程是否存在冲突,确保所有课程都能顺利完成。文章详细分析了两种算法的实现过程,包括图的构建及环检测方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

207. Course Schedule

题目链接

题目解释:总共有n种的课你需要去上,这些课标号从0到n-1。你上某些课程之前需要有一些先修课程,如你想要参加课程0,那么你必须先学习完课程1,这个可以采用一个配对来表示:[0,1]。

给出总的课程数以及先修课程匹配对,判断一下,你是否能修完所有的课程?

Example 1:

Input: 2, [[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: 2, [[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.

解释:在给出的两个课程对中,课程0和课程1互为先修课程,所以对于你来说,是不可能修完所有的课程的。

题目分析:在这里我们先分析出pair的特点,以[0,1]举例:

这是两门课程,你想要修习课程0,那么你就必须先学习课程1,即是1->0

看到这样的表示,我们应该是有一些感触的。这种表示方式是不是和我们学习的有向图很类似,在本题中,如果所有的结点都组合起来能够围成一个有向无环图,那么我们就是能够修习完所有的课程。这样我们的问题就变成了查看给定的图是否是是无环图。那么我们首先是需要构建图,然后根据拓扑排序来解决。

PS:本题讲道理来说,还是很难的,因为我们需要自己构建图,然后来判断构建的图是否是有环,但是难着难着感觉我们就习惯了,多看两遍,然后有了手感,写一下,就会发现整体来说,我们还是能解决的,索然过程还是比较痛苦的,但是这也是在代表着我们在进步,不是么?(手动打鸡血......)

class Solution(object):
    def canFinish(self, numCourses, prerequisites):
        """
        采用BFS
        :type numCourses: int
        :type prerequisites: List[List[int]]
        :rtype: bool
        """
        graph=collections.defaultdict(list)
        indegrees=collections.defaultdict(int)
        # 组建一幅图,其中u是相当于结点的第一个点,v是结点的第二条点,这就是graph代表的意义
        # 这里是先修课程,如[1,0]代表要修1,就要先修0,所以理解好入度和出度的关系,indegrees代表入度
        # 初始化建图
        for u,v in prerequisites:
            graph[v].append(u)
            indegrees[u]+=1
        for i in range(numCourses):
            zero_degree=False
            for j in range(numCourses):# 若某个结点的入度为0
                if indegrees[j]==0:
                    zero_degree=True
                    break
            if not zero_degree:
                return False
                # 结点j的入度减去1,同时在图中j指向的结点的入度减去1
            indegrees[j]-=1
            for node in graph[j]:
                indegrees[node]-=1
        return True

 

另外,用了BFS,我们同样可以尝试DFS。

    def canFinish1(self, N, prerequisites):
        """
        :type N,: int
        :type prerequisites: List[List[int]]
        :rtype: bool
        """
        graph = collections.defaultdict(list)
        for u, v in prerequisites:
            graph[u].append(v)
        # 0 = Unknown, 1 = visiting, 2 = visited
        visited = [0] * N
        for i in range(N):
            if not self.dfs(graph, visited, i):
                return False
        return True

    def dfs(self, graph, visited, i):
        if visited[i] == 1:
            return False
        if visited[i] == 2:
            return True
        visited[i] = 1
        for j in graph[i]:
            if not self.dfs(graph, visited, j):
                return False
        visited[i] = 2
        return True

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值