【问题标题】:Cracking the Coding Interview 6th Edition: 10.10. Rank from Stream破解编码面试第 6 版:10.10。来自流的排名
【发布时间】:2017-08-31 19:51:03
【问题描述】:

问题陈述如下:

假设您正在阅读整数流。定期,你 希望能够查找数字 x 的排名( 值小于或等于 x)。实现数据结构和 算法来支持这些操作。也就是说,实现方法 track (in t x),在生成每个数字时调用它,并且 方法 getRankOfNumber(int x) ,它返回值的数量 小于或等于 X(不包括 x 本身)。

示例:流(按出现顺序):5、1、4、4、5、9、7、13、3

getRankOfNumber(1) = 0 getRankOfNumber(3) = 1 getRankOfNumber(4) = 3

建议的解决方案使用修改后的二叉搜索树,其中每个节点存储该节点左侧的节点数。两种方法的时间复杂度是平衡树的 O(logN) 和不平衡树的 O(N),其中 N 是节点数。

但是我们如何从随机整数流中构造一个平衡的 BST?如果我们继续添加到同一棵树并且根不是中间值,树会不会在适当的时候变得不平衡?对于这个解决方案,最坏情况的复杂性不应该是 O(N)(在这种情况下,对于 track() 和 getRankOfNumber() 分别具有 O(1) 和 O(N) 的 HashMap 会更好)?

【问题讨论】:

  • 您可以创建一个具有 O(log n) 插入的平衡二叉树。以AVL tree 为例。
  • 谢谢@JimMischel。但是您是否同意在这种情况下,在大多数情况下,简单的 BST 不会保持平衡?
  • 不,我根本不会同意。只有当数字流以特别糟糕的顺序呈现时,才会发生最坏的情况。如果数字的分布没有任何特定的顺序,那么树应该保持合理的平衡。

标签: algorithm stream binary-search-tree


【解决方案1】:

您只需要构建一个 AVL 或红黑树即可获得所需的 O(lg n) 复杂度。

关于等级,很简单。让我们将 count(T) 称为具有根 T 的树的元素数。

  • 节点 N 的等级将是:
    • 首先在N之前会有count(N's left subtree)节点(小于N的元素)
    • 让 A = N 的父亲。如果N是A的右子,那么在N之前会有1 + count(A's left subtree)个节点
    • 如果A是某个B的正确儿子,那么在N之前会有1 + count(B's left subtree)节点
    • 递归地一直向上运行,直到到达根节点或直到您所在的节点不是某人的正确儿子。

由于平衡树的高度最多为 lg(n),因此此方法将花费 O(lg n) 来返回某人的排名( O(lg n) 找到 + O(lg n) 跑回去测量排名),但考虑到所有节点都存储其左右子树的大小。

希望有帮助:)

【讨论】:

    猜你喜欢
    • 2015-12-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-12-12
    • 2012-09-24
    • 1970-01-01
    • 2018-11-21
    • 2013-09-05
    相关资源
    最近更新 更多