# 207. Course Schedule #### Difficulty: Medium link: https://leetcode.com/problems/course-schedule/ 整個問題能被建成一個graph,每一堂課程都是node,先修關係當作edge,這題相當於在檢查整個graph是不是DAG,有沒有cycle存在。 DFS和BFS的做法都行。 ### 1. DFS #### $O(V+E)$ runtime, $O(V+E)$ space 用DFS判斷有沒有cycle,需要至少兩種node的狀態:已拜訪和正在拜訪。如果下一個要拜訪的node,恰好是正在拜訪的node,就代表有cycle。 ##### python ```python= class Solution: def canFinish(self, numCourses: int, prerequisites: List[List[int]]) -> bool: # build the adjacence list graph = [[] for _ in range(numCourses)] for v, u in prerequisites: graph[u].append(v) # visit node visited = [0 for _ in range(numCourses)] def dfs(node): if visited[node] == 1: # the node has been visited return True elif visited[node] == -1: # the node is being visited return False # the node has not been visited visited[node] = -1 for neigh in graph[node]: if not dfs(neigh): return False visited[node] = 1 return True for i in range(numCourses): if not dfs(i): return False return True ``` ### 2. BFS #### $O(1)$ runtime, $O(1)$ space 先從不需要必修的課程開始,每修完一堂課,再去檢查是否解鎖新的課程。最後,看看是不是修完了所有的課,如果修不完就代表有cycle。 ##### python ```python= class Solution: def canFinish(self, numCourses: int, prerequisites: List[List[int]]) -> bool: # build the adjacence list and calculate indegree indegree = [0] * numCourses graph = [[] for _ in range(numCourses)] for v, u in prerequisites: graph[u].append(v) indegree[v] += 1 # start from courses which have no prerequisites queue = deque() for i in range(numCourses): if indegree[i] == 0: queue.append(i) visited = 0 while queue: node = queue.popleft() visited += 1 for neigh in graph[node]: indegree[neigh] -= 1 if indegree[neigh] == 0: queue.append(neigh) return visited == numCourses ``` ###### tags: `leetcode`