破解编码专访第6版:10.10。来自Stream的排名

时间:2017-04-06 01:10:50

标签: algorithm stream binary-search-tree

问题陈述如下:

  

想象一下,您正在读取整数流。你周期性地   希望能够查找数字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)(在这种情况下,分别用于轨道()和getRankOfNumber()的O(1)和O(N)的HashMap会更好吗?

1 个答案:

答案 0 :(得分:0)

你只需要构建一个AVL或Red-Black Tree来获得你想要的O(lg n)复杂度。

关于等级,它的那种简单。让我们用根T调用count(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)来运行测量排名),但这考虑到所有节点都存储左右子树的大小。

希望有所帮助:)