LeetCode 1136. Parallel Courses - 拓扑排序(Topological Sort)系列题6

该博客讨论了LeetCode 1136问题,涉及如何使用拓扑排序算法解决确定最少学期数完成所有课程的需求。文章解释了如何通过BFS策略确保每学期修读尽可能多的课程,并确保所有先决条件得到满足。

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

You are given an integer n, which indicates that there are n courses labeled from 1 to n. You are also given an array relations where relations[i] = [prevCoursei, nextCoursei], representing a prerequisite relationship between course prevCoursei and course nextCoursei: course prevCoursei has to be taken before course nextCoursei.

In one semester, you can take any number of courses as long as you have taken all the prerequisites in the previous semester for the courses you are taking.

Return the minimum number of semesters needed to take all courses. If there is no way to take all the courses, return -1.

Example 1:

Input: n = 3, relations = [[1,3],[2,3]]
Output: 2
Explanation: The figure above represents the given graph.
In the first semester, you can take courses 1 and 2.
In the second semester, you can take course 3.

Example 2:

Input: n = 3, relations = [[1,2],[2,3],[3,1]]
Output: -1
Explanation: No course can be studied because they are prerequisites of each other.

Constraints:

  • 1 <= n <= 5000
  • 1 <= relations.length <= 5000
  • relations[i].length == 2
  • 1 <= prevCoursei, nextCoursei <= n
  • prevCoursei != nextCoursei
  • All the pairs [prevCoursei, nextCoursei] are unique.

又是一道修课题,还是LeetCode 444. Sequence Reconstruction的拓展,这道题不仅问能否修完所有课还问最少需要几学期能修完所有课。我们知道拓扑排序(Topological Sort)算法里用到了BFS,而BFS又是求最短路径最常用的方法,因此这道题用拓扑排序(Topological Sort)来解答再合适不过。

要求最少学期那就是要每学期把能修的课都给修了,也就是说每次应该把当前队列里的所有课程都取出(相当于一个学期把能修的课都修了),然后把下学期能修的课(去掉一条边入度变为0)再放入队列中,一次循环学期数加1,最后得到就是最少学期数,另外还需保证最后所有的课都能修完。

class Solution:
    def minimumSemesters(self, n: int, relations: List[List[int]]) -> int:
        indegree = [0] * (n + 1)
        graph = [[] for i in range(n +1)]
        ecnt = 0
        
        for (c1, c2) in relations:
            indegree[c2] += 1
            graph[c1].append(c2)
            ecnt += 1
        
        q = deque()
        for i in range(1, n + 1):
            if indegree[i] == 0:
                q.append(i)
        res = 0
        while q:
            cn = len(q)
            for i in range(cn):
                c1 = q.popleft()
                for c2 in graph[c1]:
                    indegree[c2] -= 1
                    if indegree[c2] == 0:
                        q.append(c2)
                    ecnt -= 1
            res += 1
        
        return res if ecnt == 0 else -1

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值