[LeetCode] 207. 课程表

题目链接:https://leetcode-cn.com/problems/course-schedule/

题目描述:

现在你总共有 n 门课需要选,记为 0 到 n-1。

在选修某些课程之前需要一些先修课程。 例如,想要学习课程 0 ,你需要先完成课程 1 ,我们用一个匹配来表示他们: [0,1]

给定课程总量以及它们的先决条件,判断是否可能完成所有课程的学习?

示例:

示例 1:

输入: 2, [[1,0]] 
输出: true
解释: 总共有 2 门课程。学习课程 1 之前,你需要完成课程 0。所以这是可能的。

示例 2:

输入: 2, [[1,0],[0,1]]
输出: false
解释: 总共有 2 门课程。学习课程 1 之前,你需要先完成课程 0;并且学习课程 0 之前,你还应先完成课程 1。这是不可能的。

说明:

  1. 输入的先决条件是由边缘列表表示的图形,而不是邻接矩阵。详情请参见图的表示法
  2. 你可以假定输入的先决条件中没有重复的边。

思路:

这道题 就是找图中是否有环。

思路一:深度优先遍历

有重复访问的,就存在环

时间复杂度 :\(O(N + E)\) \(N\) 为顶点个数,\(E\)为边的个数

思路二:广度优先遍历

通过顶点的入度的个数,每次消除入度为0顶点,看是否每一个节点都能被消除

时间复杂度 : \(O(N + E)\) \(N\) 为顶点个数,\(E\)为边的个数

代码:

DFS

class Solution:
    def canFinish(self, numCourses: int, prerequisites: List[List[int]]) -> bool:
        from collections import defaultdict
        graph = defaultdict(list)
        # 记录
        visited = set()
        # 建图
        for x, y in prerequisites:
            graph[y].append(x)

        # 深度遍历
        def dfs(i, being_visited):
            if i in being_visited: return False
            if i in visited: return True
            visited.add(i)
            being_visited.add(i)
            for j in graph[i]:
                if not dfs(j, being_visited): return False
            being_visited.remove(i)
            return True
        # 检测每门功课起始是否存在环
        for i in range(numCourses):
            # 已经访问过
            if i in visited: continue
            if not dfs(i, set()): return False
        return True

BFS

class Solution:
    def canFinish(self, numCourses: int, prerequisites: List[List[int]]) -> bool:
        from collections import defaultdict, deque
        graph = defaultdict(list)
        degree = [0] * numCourses
        # 建图
        for x, y in prerequisites:
            graph[y].append(x)
            degree[x] += 1
        queue = deque([i for i in range(numCourses) if degree[i] == 0])
        #print(queue)
        cnt = 0
        while queue:
            i = queue.pop()
            cnt += 1
            for j in graph[i]:
                degree[j] -= 1
                if degree[j] == 0:
                    queue.appendleft(j)
        return cnt == numCourses

posted on 2019-08-17 20:48  威行天下  阅读(325)  评论(0编辑  收藏  举报

导航