代码随想录 222. 完全二叉树的节点个数

130 阅读2分钟

222. 完全二叉树的节点个数 - 力扣(LeetCode)

自顶向下遍历

class Solution {
int sum; //注意sum是全局变量,根节点和孩子节点都能共享。孩子节点直接把计数加在sum上,而不传回给父亲节点。
public:
     //root先把自己计数一次,再把任务交给孩子节点,让它们自己去把自己以及孩子的孩子节点们加到sum进行计数
    int countNodes(TreeNode* root) {
        if(root==nullptr) return 0;
        sum++;
        countNodes(root->left);
        countNodes(root->right);
        return sum;
    }
};

自底向上 递归遍历

class Solution {
public:
    //root先把任务分发给孩子节点,让它们分别统计子树节点个数,再通过return传回给父节点,父节点再把自己进行计数。
    int countNodes(TreeNode* root) {
        if(root==nullptr) return 0;
        int sum=0; //这个sum负责统计当前节点以及它孩子节点的个数,父亲节点看不到这个sum。
        sum += countNodes(root->left);
        sum += countNodes(root->right);
        sum++;
        return sum;
    }
};


后序遍历

class Solution {
public:
    int countNodes(TreeNode* root) {
        
         //root先把任务分发给孩子节点,让它们分别统计子树节点个数,再通过return传回给父节点,父节点再把自己进行计数。
        if(root==nullptr)return 0;
        int leftheight=countNodes(root->left);  //左
        int rightheight=countNodes(root->right); //右
        int rootheight=1;  //根
    return leftheight+rightheight+rootheight;
    }
};

image.png

因为不管是前中后序遍历都需要把整个二叉树遍历一遍,时间复杂度为O(n),如果想提高效率就要利用完全二叉树的特性。

优化

示例1的左子树是一个节点全满的完全二叉树,它的特性是左孩子高度和右孩子高度相等。

image.png

并且可以利用树高直接求出完全二叉树节点个数:

image.png

所以我们先判断,如果左子树是完全二叉树,那么左子树就不用遍历了,直接用 公式求出节点个数,这样就省了效率。

那么求树高也是需要遍历的,我们这里遍历只遍历外侧,不用遍历全部节点。例如图(a-1):

image.png

(a-1)的左子树是节点全满的完全二叉树,根据绿色路径就可以求出左子树的高度,蓝色路径就不用走了。

code

class Solution {
public:
    int countNodes(TreeNode* root) {

    if(root==nullptr)return 0;

    //判断是否是完全二叉树。
    //遍历左子树
    TreeNode* l=root->left;
    TreeNode* r=root->right;
    int lh=0,rh=0;

    //统计树高
    while(l)
    {
        l=l->left;
        lh++;
    }

    while(r)
    {
        r=r->right;
        rh++;
    }
    
    //如果是节点全满的完全二叉树,就用特性求
    if(lh==rh){return (2<<lh)-1;}
    
    //单层搜索逻辑
    int  leftnum=countNodes(root->left); //左
    int rightnum=countNodes(root->right); //右
  int  result=leftnum+rightnum+1;         //根

    return result;
    }
};

image.png