二进制搜索树中最常见的元素

时间:2013-07-13 13:00:29

标签: algorithm

我们怎样才能找到BST中最常出现的元素?我想过用hash-map实现它。有什么简单的方法吗?

4 个答案:

答案 0 :(得分:7)

此问题等同于在排序数组中查找最常见的元素 - 应用相同的算法:

  • 启动计数器零
  • 当前元素等于前一个元素时递增计数器
  • 当您找到不同的元素时,请将计数器与当前最佳运行进行比较;必要时更换
  • 继续下一个元素

唯一的区别是,不是使用循环遍历数组,而是使用递归函数进行树遍历。在这两种情况下,算法在树中的元素数量上是线性的。如果树是平衡的,则算法在调用堆栈上需要O(LogN)空间。

答案 1 :(得分:2)

可以通过多种方式完成 -

  1. 执行BST Inorder Traversal。这将为您提供元素的排序列表。执行线性遍历以查找重复次数最多的元素。 time O(n) space O(n)
  2. Hashtable就像你说的那样。做BST的DFS traversals中的任何一个。将每个元素插入到计数设置为1的哈希表中。如果元素已存在,则递增计数+ 1。然后遍历哈希表以找出经常出现的元素。最差情况时间O(n)和空间O(n)但实际上,如果数据集有大量重复,这种方法应占用更少的空间。

答案 2 :(得分:0)

这是最干净的方法:

  • 初始化哈希映射,将值映射到其出现次数。
  • 按顺序迭代BST:
    • hash [node.value] + = 1

您可以就地执行此操作(O(1)额外的内存复杂性):

保持2 O(1)个变量表示最大出现次数和元素,按顺序迭代树,以保证它以递增方式递增,并更新元素最大出现次数:

curmax = 0
maxnode = null
for each node in BST.inorder():
    if next.value == node.value:
        max ++
    else:
        max = 1
    if max > curmax:
        curmax  = max
        maxnode = node

答案 3 :(得分:0)

我们可以使用修改后的inorder遍历,并跟踪前一个元素。

TreeNode prev = null;
int count = 1, max = 0;
List<Integer> list = new ArrayList<>();


private void inorder(TreeNode root) {
    if (root == null) return;
    inorder(root.left);
    if (prev != null) {
        if (root.val == prev.val)
            count++;
        else
            count = 1;
    }
    if (count > max) {
        max = count;
        list.clear();
        list.add(root.val);
    } else if (count == max) {
        list.add(root.val);
    }
    prev = root;
    inorder(root.right);
}

由于inorder遍历为我们提供升序的元素,这种技术很有用,这里的列表将包含这些元素。