原题目链接
你这个学期必须选修 numCourses 门课程,记为 0 到 numCourses - 1 。 在选修某些课程之前需要一些先修课程。 先修课程按数组 prerequisites 给出,其中 prerequisites[i] = [ai, bi] ,表示如果要学习课程 ai 则 必须 先学习课程 bi 。 例如,先修课程对 [0, 1] 表示:想要学习课程 0 ,你需要先完成课程 1 。 请你判断是否可能完成所有课程的学习?如果可以,返回 true ;否则,返回 false 。
示例 1: 输入:numCourses = 2, prerequisites = [[1,0]] 输出:true 解释:总共有 2 门课程。学习课程 1 之前,你需要完成课程 0 。这是可能的。 示例 2: 输入:numCourses = 2, prerequisites = [[1,0],[0,1]] 输出:false 解释:总共有 2 门课程。学习课程 1 之前,你需要先完成课程 0 ;并且学习课程 0 之前,你还应先完成课程 1 。这是不可能的。
class SolutionCourses:
def canFinish(self, numCourses: int, prerequisites: List[List[int]]) -> bool:
self.requistes_dict = defaultdict(list)
self.flag = True
for course, pre in prerequisites:
if course == pre:
return False
self.requistes_dict[str(course)].append(pre) # 可能存在一个课程依赖多个前置课程
self.courses_list = [x for x in range(numCourses)]
self.visited = [0] * numCourses
for i in range(numCourses):
self.dfs(i)
if self.flag == False:
return False
return True
def dfs(self, x):
self.visited[x] = 1 # 用1 记录本次查找中
if str(x) in self.requistes_dict.keys():
vl = self.requistes_dict[str(x)]
else:
vl = [-1]
if vl == [-1]:
pass
else:
for v in vl:
if self.visited[v] == 1:
self.flag = False
return
elif self.visited[v] == 0:
self.dfs(v) # 找下一个课程
self.visited[x] = 2 # 用2 记录已经完成一趟查找
# course_solution = SolutionCourses()
# numCourses = 5
# prerequisites = [[1,4],[2,4],[3,1],[3,2]]
# print(course_solution.canFinish(numCourses, prerequisites))
这里特别要注意课程的依赖关系,有可能有的课程谁都不依赖,也有可能同时依赖多门其他课程,只要发现了循环依赖,就可以直接返回False。