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

  • 相关阅读:
    Python并发编程-IO模型-IO多路复用实现SocketServer
    Python并发编程-IO模型-非阻塞IO实现SocketServer
    Python并发编程-协程实现socketserver
    Pytho并发编程-利用协程实现简单爬虫
    Python正则表达式中的re.S
    Python-正则表达式
    django-模板初探
    django-response对象
    django-QueryDict 对象
    django-request对象
  • 原文地址:https://www.cnblogs.com/lz87/p/7496940.html
Copyright © 2011-2022 走看看