93、【树与二叉树】leetcode ——222. 完全二叉树的节点个数:普通二叉树求法+完全二叉树性质求法(C++版本)

题目描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
原题链接:222. 完全二叉树的节点个数

解题思路

1、普通二叉树节点个数求法

(1)迭代:层序遍历BFS

遍历一层获取一层结点

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
public:
    int countNodes(TreeNode* root) {
        if(!root)       return 0;
        int res = 0;
        queue<TreeNode*> que;
        que.push(root);
        while(!que.empty()) {
            int n = que.size();
            while(n--) {
                TreeNode* node = que.front();
                que.pop();
                res++;
                if(node->left)      que.push(node->left);
                if(node->right)     que.push(node->right);
            }
        }
        return res;
    }
};

时间复杂度 O ( n ) O(n) O(n)
空间复杂度 O ( n ) O(n) O(n)

(2)递归:先序遍历DFS

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
public:
    int num = 0;		// 设置一个全局变量记录
    int countNodes(TreeNode* root) {
        if(!root)       return 0;
        num++;			// 每遍历到一个结点,就加一
        countNodes(root->left);
        countNodes(root->right);
        return num;
    }
};

时间复杂度 O ( n ) O(n) O(n)
空间复杂度 O ( l o g n ) O(log n) O(logn) (不考虑系统栈)

(3)迭代:后序遍历(子问题分解)

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
public:
    int countNodes(TreeNode* root) {
        if(!root)       return 0;
        int leftcnt = countNodes(root->left);       // 左
        int rightcnt = countNodes(root->right);     // 右
        return leftcnt + rightcnt + 1;              // 中:将结果返回给上一层
    }
};

时间复杂度 O ( n ) O(n) O(n)
空间复杂度 O ( l o g n ) O(log n) O(logn) (不考虑系统栈)

2、完全二叉树性质求节点个数

image.png
满二叉树的特点:左子树左侧边的高度=右子树右侧边的高度,节点个数= 2 n − 1 2^n-1 2n1
完全二叉树的特点:除了最后一层外,其余层全部为满二叉树。

可以将这个问题分解成子问题,求根节点所拥有的左右子树节点个的结点个数,最后得到整棵树的总个数。而每遍历到一颗子树时,可以利用满二叉树的特点查看该子树是否为一颗满二叉树,若为满二叉树,直接根据节点个数公式返回即可若为不满二叉树,则算上该节点(总结点个数加一),然后再向下递归计算其左右子树结点个数

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
public:
    int level = 0;
    int countNodes(TreeNode* root) {
        if(!root)       return 0;        
        // 先求左子树左侧高度和右子树右侧高度
        TreeNode* leftnode = root->left;
        TreeNode* rightnode = root->right;
        int leftLevel = 0, rightLevel = 0;      // 2左移从0开始,1左移从1开始
        while(leftnode) {
            leftLevel++;
            leftnode = leftnode->left;            
        }
        while(rightnode) {
            rightLevel++;
            rightnode = rightnode->right;
        }
        // 若为满二叉树,左子树左侧高度应该等于右子树右侧高度
        if(leftLevel == rightLevel)      return (2 << leftLevel) - 1;       // 2<<0 = 2 , 2<<n = 2^(n+1),因此规定从0开始
        // 若不为满二叉树,则算此结点个数,并求再求左右子树的结点个数
        return countNodes(root->left) + countNodes(root->right) + 1;
    }
};

时间复杂度 O ( l o g 2 n ) O(log^2 n) O(log2n)
空间复杂度 O ( l o g n ) O(log n) O(logn)

注: 0 < n ≤ 4 0<n≤4 0<n4时, O ( n ) ≥ O ( l o g 2 n ) O(n) ≥ O(log^2 n) O(n)O(log2n);当 n ≥ 5 n≥5 n5时, O ( n ) < O ( l o g 2 n ) O(n) < O(log^2 n) O(n)O(log2n)

参考文章:222.完全二叉树的节点个数如何计算完全二叉树的节点数

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

辰阳星宇

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值