• lintcode615- Course Schedule- medium


    There are a total of n courses you have to take, labeled from 0 to n - 1.

    Some courses may have prerequisites, for example to take course 0 you have to first take course 1, which is expressed as a pair: [0,1]

    Given the total number of courses and a list of prerequisite pairs, is it possible for you to finish all courses?

    Example

    Given n = 2, prerequisites = [[1,0]]
    Return true

    Given n = 2, prerequisites = [[1,0],[0,1]]
    Return false

     
    算法:先求拓扑序(BFS),如果课程内部有循环依赖(也即不合法),那拓扑序里元素个数会比总元素少。以此为判据
    数据结构:本题特殊,用int而非特殊对象表示课程名,所以可以直接用数组代替之前的map来表示Indegree和edges关系,直接用课程名作为数组idx来索引。
    int[] indegree, List[] edges(里面每个元素都是List<Integer>), Queue<Integer> queue + Set<Integer>(BFS用),List<Integer> order存拓扑序
    细节:1.如果没有requisite,那不管多少课都true,而非仅一节课true。2.数据结构运用实现上int next = (int)edges[course].get(i);这里要强转一下,不知道为什么取出来是Object格式的 3.这题必须用int[] indegree, List[] edges来优化原来的Map结构,否则内存会爆炸。4.感受一下List[] 是足够存储边的关系的,比int[][]要更紧凑一点,去掉稀疏部分
     
    public class Solution {
        /*
         * @param numCourses: a total of n courses
         * @param prerequisites: a list of prerequisite pairs
         * @return: true if can finish all courses or false
         */
         
    
        
        public boolean canFinish(int numCourses, int[][] prerequisites) {
            // write your code here
            
            if (prerequisites == null || prerequisites.length == 0) {
                return true;
            }
            
            // indegree map
            int[] indegree = new int[numCourses];
            List[] edges = new ArrayList[numCourses];
            
            for (int i = 0; i < numCourses; i++) {
                indegree[i] = 0;
                edges[i] = new ArrayList<Integer>();
            }
            
            for (int i = 0; i < prerequisites.length; i++) {
                int c1 = prerequisites[i][0];
                int c2 = prerequisites[i][1];
                indegree[c1] ++;
                edges[c2].add(c1);
            }
            
            Queue<Integer> queue = new LinkedList<Integer>();
            Set<Integer> set = new HashSet<Integer>();
            List<Integer> order = new ArrayList<Integer>();
            for (int i = 0; i < numCourses; i++) {
                if (indegree[i] == 0) {
                    queue.offer(i);
                    set.add(i);
                }
            }
            while (!queue.isEmpty()) {
                int course = queue.poll();
                order.add(course);
                for(int i = 0; i < edges[course].size(); i++) {
                    // 注意这里一定要加一个强制类型转换!edges[course].get(i)拿出来会是Object类型的,不能直接放到int容器里。
                    int next = (int)edges[course].get(i);
                    indegree[next] --;
                    if (indegree[next] == 0) {
                        queue.offer(next);
                        set.add(next);
                    }
                }
            }
            return numCourses == order.size();
        }
        
    }

    2.自己实现的内存爆炸的Map形式,输出正确但输入大的时候空间复杂度过高

    public class Solution {
        /*
         * @param numCourses: a total of n courses
         * @param prerequisites: a list of prerequisite pairs
         * @return: true if can finish all courses or false
         */
         
    
        
        public boolean canFinish(int numCourses, int[][] prerequisites) {
            // write your code here
            
            if (prerequisites == null || prerequisites.length == 0) {
                return true;
            }
            
            // indegree map
            Map<Integer, Integer> map = new HashMap<>();
            Map<Integer, Set<Integer>> leadMap = new HashMap<>();
            
            // req map
            for (int i = 0; i < numCourses; i++) {
                map.put(i, 0);
                leadMap.put(i, new HashSet<Integer>());
            }
            for (int i = 0; i < prerequisites.length; i++) {
                int c1 = prerequisites[i][0];
                int c2 = prerequisites[i][1];
                if (!leadMap.get(c2).contains(c1)) {
                    leadMap.get(c2).add(c1);
                    map.put(c1, map.get(c1) + 1);
                }
                
            }
            
            Queue<Integer> queue = new LinkedList<Integer>();
            Set<Integer> set = new HashSet<Integer>();
            List<Integer> order = new ArrayList<Integer>();
            for (int i = 0; i < numCourses; i++) {
                if (map.get(i) == 0) {
                    queue.offer(i);
                    set.add(i);
                }
            }
            while (!queue.isEmpty()) {
                int course = queue.poll();
                order.add(course);
                for (int next : leadMap.get(course)) {
                    map.put(next, map.get(next) - 1);
                    if (map.get(next) == 0) {
                        queue.offer(next);
                        set.add(next);
                    }
                }
            }
            return numCourses == order.size();
        }
        
    }
     
     
  • 相关阅读:
    高等数学(6) 无穷小和无穷大
    高等数学(5) 函数的极限
    高等数学(4) 数列与数列极限
    实时音视频互动系列(下):基于 WebRTC 技术的实战解析
    实时音视频互动系列(上):又拍云UTUN网络详解
    免费SSL&付费SSL证书,该如何选择?
    直播卡顿原因详解及优化
    实战解析 | 同步音视频解决方案
    从Html5直播到互动直播,看直播协议的选择
    如何将HLS延时缩短至4秒,HLS+技术详解
  • 原文地址:https://www.cnblogs.com/jasminemzy/p/7734753.html
Copyright © 2020-2023  润新知