【问题标题】:No of Nodes in which nodes are smaller and greater than the certain node节点小于和大于某个节点的节点数
【发布时间】:2019-12-15 00:10:31
【问题描述】:

给定一棵树,计算每个顶点的子树中大于该顶点的节点数和小于该顶点的节点数。

我可以通过深度优先搜索 (DFS) 找到单个顶点的答案,但对每个顶点都进行此操作肯定会花费大量时间。

我们能否更快地解决问题?

【问题讨论】:

  • 一种天真的方法:执行 DFS 并将“当前处理的顶点”列表保留为堆栈。第一次访问节点时,将其添加到堆栈中,最后一次访问后将其删除。考虑到 DFS 中的遍历顺序,这些操作是合理的。堆栈元素是元组(value, count),初始化为(value, 0)。在第一次访问每个顶点时,遍历堆栈并适当地增加计数。删除堆栈元素后,将其count 与当前节点一起存储。这在 O(n^2) 中运行(O(d*n)d 树的深度)。
  • 嗯,我需要一个更优化的解决方案,这个解决方案非常直观。

标签: c++ algorithm graph tree graph-algorithm


【解决方案1】:

更有效的方法:

一种更有效的方法是进行后排序并使用二叉​​搜索树类型映射(可能在 c++ 中排序映射实现应该已经使用某种红黑树)来存储键及其计数。

对树进行后序遍历。 在遍历后的每个节点处:

a) 对于更大的节点:

在 BST 类型映射中获取当前节点的下一个最大值(这应该在 O( log n ) 中完成并计算它下面的所有值。(这将节省大量时间,特别是如果树是平衡的)但会很昂贵如果树不平衡。

b) 对于较小的节点:

在 BST 类型映射中获取当前节点的下一个最小值(这应该在 O( log n ) 中完成并计算它上面的所有值。

//map - sorted map with keys and their count
//greater_map - unordered map that contains node as key and count of nodes greater than key node.
//lesser_map - unordered map that contains node as key and count of nodes lesser than key node.

post_order( Node root ) 
   if ( root == null ) return;

   for each child in root.children:
       post_order( child )

   int next_higher_key = find_next_higher_key( map, root_key )
   greater_map.insert(root, count_all_values_greater_than_equal_to(next_higher_key, map) )

   int next_smaller_key = find_next_smaller_key( map, root_key )
   lesser_map.insert(root, count_all_values_lesser_than_equal_to(next_smaller_key, map) )

   if ( !map[root_key] )
      map.insert( root_key, 1 )
   else
      map.insert( root_key, map[root_key] + 1 )

效率较低的方法:

对树进行一次深度优先搜索遍历。在完成遍历后的每个节点处,将较大节点和较小节点的数量存储在两个映射中。键将是您刚刚完成遍历的节点,值将分别是大于当前节点的节点数和小于当前节点的节点数。从地图中,您可以轻松地获得任何给定节点更大或更小的节点数量。

伪代码:


list_of_nodes dfs( Node root ) {
   list_of_nodes thisList = new list_of_nodes;
   if ( root == null ) return thisList;
   thisList.push( root );

   for each child in root.children:
       list_of_nodes childList = dfs( child )
       thisList.addAll( childList )

   int greater = 0, lesser = 0
   for each node in thisList:
       if node_value > root_value
           greater++
       else if node_value < root_value
           lesser++

   greatermap.insert( root, greater )
   lessermap.insert( root, lesser )

   return thisList

要获取任何给定节点的更大、更小节点的数量,您只需访问地图即可。

dfs( root_of_tree );
greater_num = greatermap[node]
lesser_num = lessermap[node]

【讨论】:

  • for each child in root.children: list_of_nodes childList = dfs( child ) thisList.addAll( childList ) 在这里,您将子树列表添加到根列表中,这可能导致二次复杂度。 @SomeDude
  • @AlexxVladisov 是的,它会增加复杂性。一种更有效的方法是使用排序映射来存储键并进行后排序。添加到我的答案中。
猜你喜欢
  • 2013-05-10
  • 2015-03-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-08-03
  • 2015-06-29
  • 2018-12-10
相关资源
最近更新 更多