zoukankan      html  css  js  c++  java
  • [LintCode] Topological Sorting

     Given an directed graph, a topological order of the graph nodes is defined as follow:

    • For each directed edge A -> B in graph, A must appear before B in the order list.
    • The first node in the order can be any node in the graph with no nodes direct to it.

    Find any topological order for the given graph.

    Example

    For graph as follow:

    picture

    The topological order can be:

    [0, 1, 2, 3, 4, 5]
    [0, 2, 3, 1, 5, 4]
    ...
    
    Challenge 

    Can you do it in both BFS and DFS?

    Solution 1. DFS, O(n + m) runtime, O(n) space

    Algorithm:

    1. for each node that has not been explored, dfs on it. The recursive dfs call stops at sinking vertices that have no outgoing edges. At the beginning of each recursive dfs call, mark the current node as explored; Before exiting each recursive dfs call, push the current graph node to a global stack.

    2. After all nodes have been explored, pop the stack and add them to the result list.

    Proof of correctness: Sinking vertices in the current subgraph are always pushed to the stack first. 

     1 /**
     2  * Definition for Directed graph.
     3  * class DirectedGraphNode {
     4  *     int label;
     5  *     ArrayList<DirectedGraphNode> neighbors;
     6  *     DirectedGraphNode(int x) { label = x; neighbors = new ArrayList<DirectedGraphNode>(); }
     7  * };
     8  */
     9 
    10 public class Solution {
    11     public ArrayList<DirectedGraphNode> topSort(ArrayList<DirectedGraphNode> graph) {
    12         ArrayList<DirectedGraphNode> result = new ArrayList<DirectedGraphNode>();
    13         if(graph == null || graph.size() == 0)
    14         {
    15             return result;
    16         }
    17         Stack<DirectedGraphNode> stack = new Stack<DirectedGraphNode>();
    18         HashSet<DirectedGraphNode> visited = new HashSet<DirectedGraphNode>();
    19         for(DirectedGraphNode node : graph)
    20         {
    21             if(!visited.contains(node))
    22             {
    23                 topSortHelper(node, visited, stack);
    24             }
    25         }
    26         while(!stack.empty())
    27         {
    28             result.add(stack.pop());
    29         }
    30         return result;
    31     }
    32     private void topSortHelper(DirectedGraphNode node,
    33                             HashSet<DirectedGraphNode> visited,
    34                             Stack<DirectedGraphNode> stack)
    35     {
    36         visited.add(node);
    37         for(DirectedGraphNode neighbor : node.neighbors)
    38         {
    39             if(!visited.contains(neighbor))
    40             {
    41                 topSortHelper(neighbor, visited, stack);
    42             }
    43         }
    44         stack.push(node);
    45     }
    46 }

    Solution 2. BFS, O(n + m) runtime, O(n) space 

    Algorithm:

    1. construct a map that stores the number of incoming edges of each graph node. O(m) runtime

    2. add graph nodes that have no incoming edges to the queue and result list. O(n) runtime

    3. dequeue nodes from the queue one at a time, and update its neighbors's incoming edges by deducting 1.

    4. if a neighbor node's incoming edges number becomes 0, add this neighbor node to the queue and the result list.

    5. repeat the steps 3 and 4 until the queue is empty. 

     1 public class Solution {
     2     public ArrayList<DirectedGraphNode> topSort(ArrayList<DirectedGraphNode> graph) {
     3         ArrayList<DirectedGraphNode> result = new ArrayList<DirectedGraphNode>();
     4         //this hash map stores how many incoming edges each node has.
     5         //if a node has 0 incoming edges, then it does not get stored in this hash map
     6         HashMap<DirectedGraphNode, Integer> map = new HashMap<DirectedGraphNode, Integer>();
     7         for(DirectedGraphNode node : graph)
     8         {
     9             for(DirectedGraphNode neighbor : node.neighbors)
    10             {
    11                 if(map.containsKey(neighbor))
    12                 {
    13                     map.put(neighbor, map.get(neighbor) + 1);
    14                 }
    15                 else
    16                 {
    17                     map.put(neighbor, 1);
    18                 }
    19             }
    20         }
    21         
    22         Queue<DirectedGraphNode> queue = new LinkedList<DirectedGraphNode>();
    23         //First add all the nodes that only have outgoing edges 
    24         //the order among these nodes do not matter
    25         for(DirectedGraphNode node : graph)
    26         {
    27             if(!map.containsKey(node))
    28             {
    29                 queue.offer(node);
    30                 result.add(node);
    31             }
    32         }
    33         while(!queue.isEmpty())
    34         {
    35             //node has been added to the result list, so we need to deduct 1
    36             //for node's all neighbors.
    37             DirectedGraphNode node = queue.poll();
    38             for(DirectedGraphNode neighbor : node.neighbors)
    39             {
    40                 map.put(neighbor, map.get(neighbor) - 1);
    41                 //neighbor has no incoming edges in the remaining subgraph
    42                 if(map.get(neighbor) == 0)
    43                 {
    44                     result.add(neighbor);
    45                     queue.offer(neighbor);
    46                 }
    47             }
    48         }
    49         return result;
    50     }
    51 }

    Related Problems

    Parallel Courses

    Course Schedule 

    Course Schedule II

    Sequence Reconstruction

  • 相关阅读:
    AfxMessageBox详细使用说明
    动态规划: 求一个一维整数数组的最大子序列和
    常见HTTP状态码
    PHP 基础系列(三) 【转】PHP 函数实现原理及性能分析
    empty() isset() isnull() 比较
    isset() 与 array_key_exists() 比较
    PHP基础系列(二) PHP数组相关的函数分类整理
    PHP基础系列(一) PHP字符串相关的函数分类整理
    linux df 命令
    grep 同时满足多个关键字和满足任意关键字
  • 原文地址:https://www.cnblogs.com/lz87/p/7496940.html
Copyright © 2011-2022 走看看