Recursion 时间复杂性问题

Recursion 时间复杂性问题,recursion,tree,time-complexity,Recursion,Tree,Time Complexity,好的,问题很简单,我们需要找到完整二叉树中所有节点的计数 我试图用下面给出的方法解决这个问题,但仍然理解时间复杂性。一些人同意O(logN^2),而另一些人则认为它甚至超过了O(N),所以可能是O(NlogN)。 请验证并提出一些更好的方法来解决此问题 int countNodes(TreeNode* root) { if(!root) return 0; int hl=0, hr=0; TreeNode *l=root, *r=root;

好的,问题很简单,我们需要找到完整二叉树中所有节点的计数

我试图用下面给出的方法解决这个问题,但仍然理解时间复杂性。一些人同意O(logN^2),而另一些人则认为它甚至超过了O(N),所以可能是O(NlogN)。 请验证并提出一些更好的方法来解决此问题

int countNodes(TreeNode* root) {
        if(!root)  return 0;
        int hl=0, hr=0;
        TreeNode *l=root, *r=root;
        while(l) { hl++; l=l->left; }
        while(r) { hr++; r=r->right;}
        if(hl==hr) return pow(2, hl)-1;
        return 1 + countNodes(root->left)+countNodes(root->right);
    }

您可以简单地计算左侧和右侧项目的数量,并将其相加:

int countNodes(TreeNode* root) {
    if(!root)  return 0;
    return 1 + countNodes(root->left)+countNodes(root->right);
}
如果我们假设所有的算法都可以在固定时间内完成(事实上就是这样,因为
int
具有固定的字长),那么它最多会产生3×n个调用(因为每个叶可以进行两个额外调用,每个调用都将
null
),所以这在线性时间内有效

首先,计算最左边的项和最右边的项的优化是不正确的,因为如果是这种情况,并且节点在树中是唯一的,那么这意味着子项的数量只是一个。即使您设法让它工作,也不会有什么不同,因为如果子对象的数量不是一,我们仍然需要通过递归执行计算


一个完整的二叉树意味着只有最后一层可以有
null
s而不是节点。但这意味着在最后一层中,最多会有⌊n/2⌋+1.我们可以在最后一层上执行二进制搜索以找出最后一层停止的位置,这确实会使它成为O(log2n):二进制搜索的O(logn),但是每个查询都需要O(h)时间来检查,并且由于树的高度与O(logn)成比例,因此我们得到O(log2n)。我把它作为一个练习来实现它。

这里的
N
是什么?@mangusta:可能是树中的项目数。你可以简单地迭代树中的项目,并跟踪数字,使其为O(N)。维护
hl
hr
是没有意义的。只要这棵树是完整的,它们就会是完整的equal@mangusta:完整的树不是完美的树。最后一级节点可以部分填充。我建议您修改答案,因为他的实现是正确的,除了冗余递归调用
返回1+…
。如果树是完整的,我们只需要找到高度并返回OP实际所在的
2^height-1
doing@mangusta:完整树不是完整树()完整树“是一种二叉树,其中除最后一级外,每一级都被完全填充,所有节点都尽可能地位于左侧”。仅对于完整的完整树(两种情况),节点数为2^h-1ah,没错。我把完整的树和完整的树混淆了ones@WillemVanOnsem我不确定二进制搜索方法。你能在这里输入一些代码吗。我会很高兴的@曼古斯塔:你能修复递归部分中的冗余部分吗。