码迷,mamicode.com
首页 > 其他好文 > 详细

[LintCode] Topological Sorting

时间:2017-11-07 14:25:59      阅读:168      评论:0      收藏:0      [点我收藏+]

标签:stat   poll   queue   help   link   begin   direct   his   time   

 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 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:

技术分享

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

Course Schedule 

Course Schedule II

Sequence Reconstruction

[LintCode] Topological Sorting

标签:stat   poll   queue   help   link   begin   direct   his   time   

原文地址:http://www.cnblogs.com/lz87/p/7496940.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!