一旦我接受了#34;一家知名公司的采访"面试官让我找到BST的中位数。
int median(treeNode* root)
{
}
我开始实施我提出的第一个蛮力解决方案。我将所有数据填充到带有inorder遍历的std::vector<int>
中(以便在向量中对所有内容进行排序)并获得中间元素。
所以我的算法是O(N),用于插入向量中的每个元素,并使用O(1),+ O(N)的内存查询中间元素。
那么做同样的事情是否有更有效的方式(在记忆方面或在复杂性方面)
提前致谢。
答案 0 :(得分:5)
可以通过有序遍历在O(n)
时间和O(logN)
空间中完成,当您到达n/2
节点时停止,只需带一个告诉您如何已经遍历了许多节点 - 无需实际填充任何向量。
如果你可以将你的树修改为rank-tree(每个节点也有关于子树中节点数量的信息,那么它是你的根) - 你可以在O(logN)时间内通过简单的方法解决它向前移动n / 2个元素的方向。
答案 1 :(得分:1)
二叉树为您的数据提供了一个排序视图,但为了利用它,您需要知道每个子树中有多少个元素。所以没有这些知识,你的算法就够快了。
如果您知道每个子树的大小,则每次都要选择访问左侧或右侧子树,如果二叉树是平衡的,则会给出O(log n)
算法。
答案 2 :(得分:1)
由于您知道中位数是元素排序列表的中间元素,因此您可以只进行顺序遍历的中间元素并停在那里,而不将值存储在向量中。如果您不知道节点数,则可能需要两次遍历,但它会使解决方案使用更少的内存(O(h)
其中h
是树的高度; h = O(log n)
表示平衡搜索树)。
如果您可以扩充树,则可以使用我提供的解决方案here来获取O(log n)
算法。