zoukankan      html  css  js  c++  java
  • (番外)使用DFS和BFS实现拓扑排序

    1.BFS实现

    public class Solution {
        public int[] findOrder(int numCourses, int[][] prerequisites) {
            int[] incLinkCounts = new int[numCourses];
            List<List<Integer>> adjs = new ArrayList<>(numCourses);
            initialiseGraph(incLinkCounts, adjs, prerequisites);
        //return solveByBFS(incLinkCounts, adjs);
            return solveByBFS(incLinkCounts,adjs);
        }
        
        private void initialiseGraph(int[] incLinkCounts, List<List<Integer>> adjs, int[][] prerequisites){
            int n = incLinkCounts.length;
            while (n-- > 0) adjs.add(new ArrayList<>());
            for (int[] edge : prerequisites) {
                incLinkCounts[edge[0]]++;
                adjs.get(edge[1]).add(edge[0]);
            }
       }
       
       private int[] solveByBFS(int[] incLinkCounts, List<List<Integer>> adjs){
           int[] order = new int[incLinkCounts.length];
           Queue<Integer> toVisit = new ArrayDeque<>();
           for (int i = 0; i < incLinkCounts.length; i++) {
               if (incLinkCounts[i] == 0) toVisit.offer(i);
                }
           int visited = 0;
           while (!toVisit.isEmpty()) {
               int from = toVisit.poll();
               order[visited++] = from;
               for (int to : adjs.get(from)) {
                   incLinkCounts[to]--;
                   if (incLinkCounts[to] == 0) toVisit.offer(to);
               }
           }
        return visited == incLinkCounts.length ? order : new int[0]; 
       }
    }
    

    2.DFS实现

    public class Solution {
        public int[] findOrder(int numCourses, int[][] prerequisites) {
            int[] incLinkCounts = new int[numCourses];
            List<List<Integer>> adjs = new ArrayList<>(numCourses);
            initialiseGraph(incLinkCounts, adjs, prerequisites);
        //return solveByBFS(incLinkCounts, adjs);
            return  solveByDFS(adjs);
        }
        
        private void initialiseGraph(int[] incLinkCounts, List<List<Integer>> adjs, int[][] prerequisites){
            int n = incLinkCounts.length;
            while (n-- > 0) adjs.add(new ArrayList<>());
            for (int[] edge : prerequisites) {
                incLinkCounts[edge[0]]++;
                adjs.get(edge[1]).add(edge[0]);
            }
       }
       
       private int[] solveByBFS(int[] incLinkCounts, List<List<Integer>> adjs){
           int[] order = new int[incLinkCounts.length];
           Queue<Integer> toVisit = new ArrayDeque<>();
           for (int i = 0; i < incLinkCounts.length; i++) {
               if (incLinkCounts[i] == 0) toVisit.offer(i);
                }
           int visited = 0;
           while (!toVisit.isEmpty()) {
               int from = toVisit.poll();
               order[visited++] = from;
               for (int to : adjs.get(from)) {
                   incLinkCounts[to]--;
                   if (incLinkCounts[to] == 0) toVisit.offer(to);
               }
           }
        return visited == incLinkCounts.length ? order : new int[0]; 
       }
       
       private int[] solveByDFS(List<List<Integer>> adjs) {
           BitSet hasCycle = new BitSet(1);
           BitSet visited = new BitSet(adjs.size());
           BitSet onStack = new BitSet(adjs.size());
           Deque<Integer> order = new ArrayDeque<>();
           for (int i = adjs.size() - 1; i >= 0; i--) {
               if (visited.get(i) == false && hasOrder(i, adjs, visited, onStack, order) == false) return new int[0];
           }
           int[] orderArray = new int[adjs.size()];
           for (int i = 0; !order.isEmpty(); i++) orderArray[i] = order.pop();
           return orderArray;
       }
    
    private boolean hasOrder(int from, List<List<Integer>> adjs, BitSet visited, BitSet onStack, Deque<Integer> order) {
        visited.set(from);
        onStack.set(from);
        for (int to : adjs.get(from)) {
            if (visited.get(to) == false) {
                if (hasOrder(to, adjs, visited, onStack, order) == false) return false;
            } else if (onStack.get(to) == true) {
                return false;
            }
        }
        onStack.clear(from);
        order.push(from);
        return true;
       }
    }
    

      

  • 相关阅读:
    ADODB.Stream
    今天发现一个好玩的翻译接口
    有趣的对角线公式
    jboss 虚拟路径
    省市区拆分字符串
    jboss-eap-6.2修改端口号
    把excel、txt当数据库来查询
    TS流PAT/PMT详解
    iOS/iPhone 程序文件目录结构以及启动流程
    onvif规范的实现:onvif开发常用调试方法 和常见的segmentation fault错误
  • 原文地址:https://www.cnblogs.com/mlz-2019/p/4716506.html
Copyright © 2011-2022 走看看