【问题标题】:Best way to select the ith smallest number of a delimited sequence of numbers选择分隔数字序列中第 i 个最小数字的最佳方法
【发布时间】:2011-04-17 13:22:40
【问题描述】:

如果给定一组数字(为方便起见,我将其存储在平衡二叉搜索树中),那么我想回答一个查询,该查询要求我告知 [A,B] 之间的第 i 个最小数字是多少,执行该任务的快速算法是什么?

从技术上讲,我可以从根遍历树搜索 A(或者如果 A 不存在,则立即大于该数字),而不是回溯搜索 B(或小于 B 的数字),同时我可以保持i 的计数器,以确定我何时会在第 i 号。但这对我来说似乎不是最优的。

我可以对用于存储通用数字集的树的高度 O(log n) 执行此操作吗?

谢谢

【问题讨论】:

  • 我想我在这里弄错了,但是您不能只搜索立即大于 A 的值,然后遍历 i-1 次吗?它是一个二叉搜索树,所以它是排序的,不是吗?我想象你的树是这样的:en.wikipedia.org/wiki/File:AVLtreef.svg - 在这个例子中,f.e.在 [15,60] 中搜索第 4 个最小的数会导致结果 50,对吗?
  • @schnaader 我猜,他想在大小为 100000 的树中搜索第 50000 个数字 :) 但如果 k 很小,你的方式肯定是最佳的。跨度>
  • @Nikita:感谢您的澄清。
  • @schanaader 没错。我的算法必须适用于大型数据集,例如,我可以有 100k 个随机数,然后给我一个范围,可以是 [10, 250],然后我会被要求找到我的第 27 个最小数字数据集(存储在 AVL 树中),并且也在给定的区间内

标签: algorithm optimization search binary-tree big-o


【解决方案1】:

如果您可以在节点中保留一些信息,您当然可以这样做。为了遍历O(logn),我们需要让每个节点知道它的右子树有多少个节点。 (您可以维护此信息,并且仍然需要在 O(log(n)) 时间内添加/删除树)

def search(currentNode, k)
    if k == 0 then
        return currentNode
    else if currentNode.rightBranchSize >= k then
        // we remove 1 from k because currentNode isn't considered anymore
        return search(currentNode.right, k - 1)
    else
        // we decrease k because currentNode and its whole right subtree aren't considered anymore
        return search(currentNode.parent, k - currentNode.rightBranchSize - 1)
    end
end

代码应该是不言自明的。
我们从currentNode 作为编号为>= A 的第一个节点开始,寻找第k 个元素(k 是从0 开始的)。

  1. 作为 schnaader 在他的评论中,如果 k 是 小。
  2. 大多数广泛使用的库(如 STL)不允许您以这种方式遍历树(它们不提供任何类型的带有指向左右子树的指针的 Node 结构)。因此,虽然算法很简单,但实现起来可能很困难。
  3. 只需稍作修改即可从您的问题中考虑B

【讨论】:

  • 您好 Nikkita,感谢您的回复。我实际上已经记住了您描述的算法。但我的想法是,如果我首先运行搜索以找到 A(并使用您的命名法确定我的 currentNode),然后我回溯我的树,在搜索区间中的第 i 个数字时检查子树上的元素数在A和B之间(或确定它不存在),我是否不必再执行一些操作,这样做,我的复杂性将大于O(log n),因为这本身就是它的时间带我去搜索A?非常感谢;)
  • @AlexTex 找到第一个数字 >= A 在二叉树中需要 O(logn) 时间。我描述的算法也需要 O(logn) 时间。并且 O(logn + logn) == O(logn),所以整个算法需要 O(logn) 时间。 (假设您已经计算了子树大小)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-08-28
  • 1970-01-01
  • 1970-01-01
  • 2010-09-26
  • 2013-07-11
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多