Leetcode 207 Course Schedule 笔记

227 阅读2分钟

Medium

思想

  • 图(graph), 有向图,单向
  • 拓扑排序, 每个顶点一个入度,一个出度。此题关心点为“入度”
  • 每次输出一个点后,就需要将这个点从图中抹掉,其后置点的入度就会-1
  • 每次输出入度为0的点,意为已修完所有前置课程
  • 遍历给定二维数组,统计所有顶点的入度
  • 从入度为0的点开始,做BFS遍历

过程

  • 定义数组:存每个顶点的入度
  • 定义map:key->顶点数据; value->该顶点的右侧邻接顶点(list)
  • 如何得到map(图)?
  • for循环遍历二维数组,完成数组和map
  • 每个pair的左边是要上的课,就在数组里+1,入度+1
  • pair右边是前置课,就是map的key值。
  • 如果map里有,就把当前key的value list中加一个这个pair左边的课,就是完成右边前置课才能上的课(这里map和给定数组的左右是相反的,有点混乱)
  • 如果没有,就new一个arraylist,把左边的课放进去,之后和右边的课一起放进map里
  • 如何通过图得到拓扑排序?BFS
  • 先把所有初始入度为0的排进queue
  • 开始BFS
  • queue里都是入度为0的课程,poll出一个,新建list等于这个poll出值在map里的value list
  • for循环将list里的值的入度逐个减1,注意判定条件要兼顾这个list是否为null
  • 每次减完1后立刻判定入度是否为0,如果为0,则加入queue
  • BFS结束后判定入度数组是否都为0,是则true,不是返回false

代码

class Solution {
    public boolean canFinish(int numCourses, int[][] prerequisites) {
        int h = prerequisites.length;
        
        int[] inDegree = new int[numCourses];
        Map<Integer, List<Integer>> map = new HashMap<>();
        
        for(int i = 0; i < h; i++){
            inDegree[prerequisites[i][0]]++;
            if(map.containsKey(prerequisites[i][1])){
                map.get(prerequisites[i][1]).add(prerequisites[i][0]);
            }else{
                List<Integer> list = new ArrayList<>();
                list.add(prerequisites[i][0]);
                map.put(prerequisites[i][1], list);
            }
        }
        
        Queue<Integer> q = new LinkedList<>();
        for(int i = 0; i < numCourses; i++){
            if(inDegree[i] == 0)
                q.offer(i);
        }
        
        while(!q.isEmpty()){
            int cur = q.poll();
            List<Integer> curList = map.get(cur);
            for(int i = 0; curList != null && i < curList.size(); i++){
                inDegree[curList.get(i)]--;
                if(inDegree[curList.get(i)] == 0)
                    q.offer(curList.get(i));
            }
            
        }   
        
        for(int i = 0; i < numCourses; i++){
           if(inDegree[i] != 0)
               return false;
        }
        return true;
        
    }
}