给定BST和两个整数'a'和'b'(a< b),我们如何找到节点的数量,使得a<节点值< b,在O(log n)?
我知道可以在LogN时间内轻松找到a和b的位置,但如何在不进行遍历的情况下计算其间的节点,即O(n)?
答案 0 :(得分:6)
在二进制搜索树的每个节点中,还要保留树中值小于其值的值的数量(或者,对于下面脚注中提到的不同树设计,其左子树中的节点)
现在,首先找到包含值a
的节点。获取小于a
的值的计数,该值已存储在此节点中。这一步是Log(n)。
现在找到包含值b
的节点。获取存储在此节点中的值小于b
的值。这一步也是Log(n)。
减去这两个计数,你有a
和b
之间的节点数。此搜索的总复杂度为2 * Log(n)= O(Log(n))。
请参阅this video。教授通过使用Splay Trees解释了你的问题。
答案 1 :(得分:0)
将BST的inorder遍历存储在数组中(它将被排序)。搜索' a'和' b'将记录log(n)时间并得到他们的索引并采取差异。这将给出范围内的节点数量' a'到' b'。
空间复杂度O(n)
答案 2 :(得分:0)
简单的解决方案:
如果Node不在范围内,则检查范围内的值。如果范围值小于根,则绝对可能的方案为左子树。否则检查右子树
这是示例代码。希望能清除。
if (node == null) {
return 0;
} else if (node.data == x && node.data == y) {
return 1;
} else if (node.data >= x && node.data <= y) {
return 1 + nodesWithInRange(node.left, x, y) + nodesWithInRange(node.right, x, y);
} else if (node.data > x && node.data > y) {
return nodesWithInRange(node.left, x, y);
} else {
return nodesWithInRange(node.right, x, y);
}
时间复杂度:-O(登录)+ O(K)
K是x和y之间的元素数。
这不是很理想,但是如果您不想修改二叉树节点的定义,那就很好了。
答案 3 :(得分:-1)
想法很简单。
时间复杂度为O(height + number of nodes in range)
..
对于你的问题,为什么它不是O(n)
。
因为我们没有遍历整个树,即树中节点的数量。我们只是根据父母的数据遍历所需的子树。
伪代码
int findCountInRange(Node root, int a, int b){
if(root==null)
return 0;
if(root->data <= a && root->data >= b)
return 1 + findCountInRange(root->left, a, b)+findCountInRange(root->right, a, b);
else if(root->data < low)
return findCountInRange(root->right, a, b);
else
return findCountInRange(root->left, a, b);
}