現(xiàn)在你總共有 n 門課需要選,記為 0 到 n-1。
在選修某些課程之前需要一些先修課程铺董。 例如,想要學(xué)習(xí)課程 0 榆芦,你需要先完成課程 1 柄粹,我們用一個匹配來表示他們: [0,1]
給定課程總量以及它們的先決條件,返回你為了學(xué)完所有課程所安排的學(xué)習(xí)順序匆绣。
可能會有多個正確的順序驻右,你只要返回一種就可以了。如果不可能完成所有課程崎淳,返回一個空數(shù)組堪夭。
輸入: 4, [[1,0],[2,0],[3,1],[3,2]]
輸出: [0,1,2,3] or [0,2,1,3]
解釋: 總共有 4 門課程。要學(xué)習(xí)課程 3拣凹,你應(yīng)該先完成課程 1 和課程 2森爽。并且課程 1 和課程 2 都應(yīng)該排在課程 0 之后。
因此嚣镜,一個正確的課程順序是 [0,1,2,3] 爬迟。另一個正確的排序是 [0,2,1,3] 。
dfs的解法:遍歷沒有visit的課程菊匿,然后對遍歷到的課程付呕,對其使用dfs,看它的后續(xù)課程能否滿足訪問條件跌捆,不形成環(huán)徽职,訪問u,如果u的相鄰結(jié)點佩厚,也就是說graph[u]d都已經(jīng)被訪問過了姆钉,那么就把u加入到visit棧中,u滿足在u的所有后驅(qū)節(jié)點的前面抄瓦,這樣看的結(jié)果是,visit從棧頂?shù)綏5壮逼浚詈髮isit表反序就是正確答案
class Solution:
def __init__(self):
self.flag=True
def findOrder(self, numCourses: int, prerequisites: List[List[int]]) -> List[int]:
def dfs(u):
be_visited.append(u)
for i in graph[u]:
if i in be_visited:
self.flag=False
elif i in visited:
pass
else:
dfs(i)
be_visited.remove(u)
visited.append(u)
graph={k:[] for k in range(numCourses)}
visited=[]
be_visited=[]
for x in prerequisites:
graph[x[1]].append(x[0])
for i in range(numCourses):
if i not in visited:
dfs(i)
return visited[::-1] if self.flag else []
BFS的方法:使用graph記錄圖的字典形式,使用indeg記錄每個結(jié)點的入度
首先闺鲸,在隊列q中初始化為當(dāng)前入度為0的點
然后循環(huán)這個隊列筋讨,取出隊列的頭部u,加入到result結(jié)果中摸恍,對u的每一個鄰居悉罕,也就是u的后修課程,v其入度減一立镶,如果v入度為0壁袄,則加入到隊列中,一直到隊列為空.
判斷此時的result結(jié)果是否是num個媚媒,否則證明有環(huán)出現(xiàn)
import collections
class Solution:
def findOrder(self, numCourses: int, prerequisites: List[List[int]]) -> List[int]:
graph=collections.defaultdict(list)
indeg=[0]*numCourses
for x in prerequisites:
graph[x[1]].append(x[0])
indeg[x[0]]+=1
q=collections.deque([u for u in range(numCourses) if indeg[u]==0])
result=[]
while q:
u=q.popleft()
result.append(u)
for v in graph[u]:
indeg[v]-=1
if indeg[v]==0:
q.append(v)
if len(result)!=numCourses:
result=[]
return result