假设可以上完课程表,利用字典创建图,键为起点,值为终点,也就是[a,b]学a要先学b,就是b指向a,然后一个访问数组表示是否上过这个课,0没有,1正在上,2上过了。对课程表里的每个课程都进行遍历需要进入深度遍历的递归。
深度遍历的递归的函数就是,当前课程正在上为1然后在图里能学的课程往后走,如果后一个课程也没学过就进入递归往后上,直到存在环就上不完课程表返回,或者后一个课程也在上为1,上不完返回,正常退出就上完这个课了为2并记录啥时候上的
python里面改变全局的整个值需要在函数nonlocal一下,改变数组啊字典啊其中某个的值不需要nonlocal
#python
class Solution:
def canFinish(self, numCourses: int, prerequisites: List[List[int]]) -> bool:
tu=collections.defaultdict(list)
v=[0]*numCourses
re=[]
ans=True
for i in prerequisites:
tu[i[1]].append(i[0])
def dfs(a):
nonlocal ans
v[a]=1
for i in tu[a]:
if v[i]==0:
dfs(i)
if not ans:
return
elif v[i]==1:
ans=False
return
v[a]=2
re.append(a)
for i in range(numCourses):
if not v[i] and ans:
dfs(i)
return ans
广度遍历,拓扑结构
字典构图如上,但排查的是入度,[a,b]学a要先学b即b指向a,a增加入度,结合队列,先将入度为0的入队。
然后进入队列的循环逐个出队,出队时计数上的课程数,同时在图中看下一个课程,下一个课程入度减1,如果该课程入度为0也可以入队,直到队列为空
最后判断上的课程是否和输入的课程数相同判断能不能上完课程表
#python
class Solution:
def canFinish(self, numCourses: int, prerequisites: List[List[int]]) -> bool:
tu=collections.defaultdict(list)
r=[0]*numCourses
for i in prerequisites:
tu[i[1]].append(i[0])
r[i[0]]+=1
v=0
q=collections.deque([i for i in range(numCourses) if r[i]==0])
while q:
v+=1
a=q.popleft()
for i in tu[a]:
r[i]-=1
if r[i]==0:
q.append(i)
return v==numCourses