求二叉搜索树的中位数,C++
Find the median of binary search tree, C++
有一次面试"One well known company",面试官让我求BST的中位数。
int median(treeNode* root)
{
}
我开始实施我想出的第一个暴力解决方案。我将所有数据填充到一个 std::vector<int>
中,并进行中序遍历(以对向量中的所有内容进行排序)并获得中间元素。
所以我的算法是 O(N),用于将每个元素插入向量中,并使用 O(1) + O(N) 的内存查询中间元素。
那么有没有更有效的方法(在内存方面或在复杂性方面)来做同样的事情。
提前致谢。
二叉树为您的数据提供了一个排序视图,但为了利用它,您需要知道每个子树中有多少个元素。因此,如果不了解这些知识,您的算法就足够快了。
如果你知道每个子树的大小,你每次 select 访问左子树或右子树,如果二叉树是平衡的,这会给出一个 O(log n)
算法。
既然你知道中位数是排序元素列表的中间元素,你可以只取中序遍历的中间元素并停在那里,而不将值存储在向量中。如果您不知道节点数,您可能需要两次遍历,但这将使解决方案使用更少的内存(O(h)
,其中 h
是树的高度;h = O(log n)
对于平衡搜索树)。
如果你可以扩充树,你可以使用我给出的解决方案 here 来获得 O(log n)
算法。
可以在O(n)
时间和O(logN)
space完成,方法是中序遍历,到达第n/2
个节点时停止,携带即可一个计数器,告诉您已经遍历了多少个节点 - 无需实际填充任何向量。
如果你可以将你的树修改为等级树(每个节点也有关于它作为根的子树中节点数的信息) - 你可以在 O(logN) 时间内轻松解决它,只需移动朝着n/2个元素的方向。
有一次面试"One well known company",面试官让我求BST的中位数。
int median(treeNode* root)
{
}
我开始实施我想出的第一个暴力解决方案。我将所有数据填充到一个 std::vector<int>
中,并进行中序遍历(以对向量中的所有内容进行排序)并获得中间元素。
所以我的算法是 O(N),用于将每个元素插入向量中,并使用 O(1) + O(N) 的内存查询中间元素。
那么有没有更有效的方法(在内存方面或在复杂性方面)来做同样的事情。
提前致谢。
二叉树为您的数据提供了一个排序视图,但为了利用它,您需要知道每个子树中有多少个元素。因此,如果不了解这些知识,您的算法就足够快了。
如果你知道每个子树的大小,你每次 select 访问左子树或右子树,如果二叉树是平衡的,这会给出一个 O(log n)
算法。
既然你知道中位数是排序元素列表的中间元素,你可以只取中序遍历的中间元素并停在那里,而不将值存储在向量中。如果您不知道节点数,您可能需要两次遍历,但这将使解决方案使用更少的内存(O(h)
,其中 h
是树的高度;h = O(log n)
对于平衡搜索树)。
如果你可以扩充树,你可以使用我给出的解决方案 here 来获得 O(log n)
算法。
可以在O(n)
时间和O(logN)
space完成,方法是中序遍历,到达第n/2
个节点时停止,携带即可一个计数器,告诉您已经遍历了多少个节点 - 无需实际填充任何向量。
如果你可以将你的树修改为等级树(每个节点也有关于它作为根的子树中节点数的信息) - 你可以在 O(logN) 时间内轻松解决它,只需移动朝着n/2个元素的方向。