课程表
题目描述:
解题思路:
Python3
- 第一种:这个方法就是先将这所有的匹配用字典的方式储存,然后按照入度依次移除没有先修课程的课,即没有入度的节点。然后每次学完之后都要通过
remove
删除。最后当某个课程的先修课程全部学完了,则这个课程就要从字典中删除,然后它就会变成没有入度的结点,后续也会删除。最后就看列表中是否还有没修完的课,如果全部修完,也就是列表为空,即返回True
,否则返回Talse
。 - 时间复杂度:O(N^3)
class Solution:
def canFinish(self, numCourses: int, prerequisites: List[List[int]]) -> bool:
dic = {}
for i, j in prerequisites:
if i in dic:
dic[i] = dic[i] + [j]
else:
dic[i] = [j]
Num = numCourses + 1
Cour = list(range(numCourses))
while len(Cour) < Num:
Num = len(Cour)
for k in Cour:
if k not in dic:
Cour.remove(k)
for x in list(dic.keys()):
if k in dic[x]:
dic[x].remove(k)
if not dic[x]:
dic.pop(x)
return Cour == []
- 第二种:广度优先遍历(拓扑排序)。
- 先生成一个入度表,然后建立一个队列然后将所有入度为 0 的节点入队,只要队列中有元素,就依次将首结点出队,并在课程表中删除该结点。每次出队时,
numCourses
都会减 1 ,这样使得拓扑排序最后出对个数等于课程次数,从而通过判断numCourses == 0
来得到最终结果。 - 时间复杂度:O(N + M)
from collections import deque
class Solution:
def canFinish(self, numCourses: int, prerequisites: List[List[int]]) -> bool:
RdFrame = [0 for _ in range(numCourses)]
adjacency = [[] for _ in range(numCourses)]
Queue = deque()
for cur, pre in prerequisites:
RdFrame[cur] += 1
adjacency[pre].append(cur)
for i in range(len(RdFrame)):
if not RdFrame[i]:
Queue.append(i)
while Queue:
pre = Queue.popleft()
numCourses -= 1
for k in adjacency[pre]:
RdFrame[k] -= 1
if not RdFrame[k]:
Queue.append(k)
return not numCourses