zoukankan      html  css  js  c++  java
  • 207. Course Schedule

    一、题目

      1、审题

      

      2、分析

        给出顶点数、指向当前顶点的前驱顶点,判断当前顶点组成的图是否是一个有向无环图。

    二、解答

      1、思路:

        方法一、

          采用拓扑排序

          ①、定义数组 matrix[][] 存储从 i 指向 j 的边,curArr[] 存储指向当前顶点的边数。并初始化这两个数组;

          ②、将没有前驱的顶点存入队列中,依次出列;

          ③、将出列的顶点为起始的边依次去除,即将 curArr[i] 值 -1;若 curArr[i] == 0,则 i 入队列;

          ④、最终队列为空时,若总共入队的元素个数与顶点个数相等,则为有向无环图,否则,为有环图。

        public boolean canFinish2(int numCourses, int[][] prerequisites) {
            
            int[][] matrix = new int[numCourses][numCourses];    // 存储边
            int[] curArr = new int[numCourses];            // curArr[m] = n: 有 n 个指针指向 m 
            
            for (int i = 0; i < prerequisites.length; i++) {
                int pre = prerequisites[i][1];
                int cur = prerequisites[i][0];
                
                if(matrix[pre][cur] == 0)
                    curArr[cur] = 1;
                matrix[pre][cur] = 1;
            }
            
            Queue<Integer> queue = new LinkedList<>();
            for (int i = 0; i < numCourses; i++) {
                if(curArr[i] == 0)
                    queue.offer(i);
            }
            
            int count = 0;
            while(!queue.isEmpty()) {
                count++;
                int course = queue.poll();
                for (int i = 0; i < numCourses; i++) {
                    if(matrix[course][i] != 0 && --curArr[i] == 0)
                        queue.offer(i);
                }
            }
            return count == numCourses;
        }

      方法二、

        采用 DFS

        ①、首先构造图,用 Map 存储,Key 为顶点,value 为直接前驱顶点;

        ②、往前驱顶点进行深度遍历图中每个顶点,判断是否该顶点重复出现,若是,返回 false;

        ③、遍历完途中的所有顶点,返回 true;

        public boolean canFinish(int numCourses, int[][] prerequisites) {
            if(prerequisites == null)
                return false;
            
            // key: 当前顶点, value: 所有直接前驱顶点
            HashMap<Integer, List<Integer>> grap = new HashMap<>();
            for(int[] curPair: prerequisites) {
                List<Integer> match = grap.get(curPair[0]);
                if(match == null) {
                    match = new ArrayList<Integer>();
                    match.add(curPair[1]);
                    grap.put(curPair[0], match);
                }
                else {
                    match.add(curPair[1]);
                }
            }
            
            HashSet<Integer> prevRoots = new HashSet<>();
            for(Integer curRoot: grap.keySet()) {
                boolean[] hasCircle = new boolean[1];
                DFS(prevRoots, curRoot, grap, hasCircle);
                if(hasCircle[0])
                    return false;
            }
            return true;
        }
        
        private void DFS(HashSet<Integer> prevRoots, Integer start,
                HashMap<Integer, List<Integer>> grap, boolean[] hasCircle) {
            
            if(hasCircle[0])    // 跳出条件
                return;
            else if(prevRoots.contains(start)) {
                hasCircle[0] = true;
                return;
            }
            
            prevRoots.add(start);
            List<Integer> match = grap.get(start);
            if(match != null) {
                for(Integer newStart: match)
                    DFS(prevRoots, newStart, grap, hasCircle);
            }
            prevRoots.remove(start);
        }
  • 相关阅读:
    SharePoint 2013 图文开发系列之自定义字段
    SharePoint 2013 图文开发系列之Visual Studio 创建母版页
    SharePoint 2013 图文开发系列之代码定义列表
    SharePoint 2013 图文开发系列之计时器任务
    SharePoint 2013 图文开发系列之应用程序页
    SharePoint 2013 图文开发系列之事件接收器
    SharePoint 2013 图文开发系列之可视化WebPart
    SharePoint 2013 图文开发系列之WebPart
    SharePoint 2013 对二进制大型对象(BLOB)进行爬网
    SharePoint 2013 状态机工作流之日常报销示例
  • 原文地址:https://www.cnblogs.com/skillking/p/9845736.html
Copyright © 2011-2022 走看看