207. 课程表(拓扑排序)

207. 课程表

难度⭐⭐

你这个学期必须选修 numCourse 门课程,记为 0numCourse-1

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

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

示例 1:

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

分析

根据题意可以将课程之间的关系以有向图的方式存储,节点之间的连接表示关系,边的权重可以用先修课程数表示(记为节点的入度)

  1. 遍历求出每个节点的入度(先修数),并存储图
  2. 由于入度数表示先修数,入度为0的课程可以修
  3. 将入度为0节点入队列(BFS),每有一个邻接节点就将入度减一
  4. 判断可修课程数是否等于总课数
class Solution:
    def canFinish(self, numCourses: int, prerequisites: List[List[int]]) -> bool:
        from collections import defaultdict
        graph = defaultdict(list)
        indeg = [0]*numCourses
        #存储图以及入度
        for rel in prerequisites:
            indeg[rel[0]] += 1
            graph[rel[1]].append(rel[0])

        #BFS 入度0节点入队列 
        res = []
        q = [cou for cou,deg in enumerate(indeg) if deg == 0]
        while q:
            node = q.pop(0)
            res.append(node)
            for i in graph[node]:#判断邻接节点入度是否为0(可以入队列)
                indeg[i] -= 1
                if indeg[i] == 0:
                    q.append(i)
        return True if len(res) == numCourses else False
class Solution {
    public boolean canFinish(int numCourses, int[][] prerequisites) {
        //定义邻接矩阵和存储入度的数组
        List<List<Integer>> graph = new ArrayList<List<Integer>>();
         for (int i = 0; i < numCourses; ++i) {
            graph.add(new ArrayList<Integer>());
        }
        int[] indeg = new int[numCourses];

        for(int[] info : prerequisites){
            indeg[info[0]] += 1;
            graph.get(info[1]).add(info[0]);
        }

        //BFS 创建队列 入度为0入队
        Queue<Integer> q = new LinkedList<Integer>();
        for(int i=0; i<numCourses; i++){
            if(indeg[i] == 0) q.offer(i);
        }

        while(!q.isEmpty()){
            int node = q.poll();
            numCourses--;
            for (int v: graph.get(node)) {
                --indeg[v];
                if (indeg[v] == 0) {
                    q.offer(v);
                }
            }
        }
        return numCourses == 0;
    }
}
posted @ 2020-08-04 10:27  鱼与鱼  阅读(201)  评论(0编辑  收藏  举报