【力扣-二叉树】6、完全二叉树的节点个数(222)

314 阅读2分钟

「这是我参与11月更文挑战的第14天,活动详情查看:2021最后一次更文挑战

222. 完全二叉树的节点个数

题目描述

给你一棵 完全二叉树 的根节点 root ,求出该树的节点个数。

完全二叉树 的定义如下:在完全二叉树中,除了最底层节点可能没填满外,其余每层节点数都达到最大值,并且最下面一层的节点都集中在该层最左边的若干位置。若最底层为第 h 层,则该层包含 1~ 2h 个节点。

 

示例 1:

输入: root = [1,2,3,4,5,6]
输出: 6

示例 2:

输入: root = []
输出: 0

示例 3:

输入: root = [1]
输出: 1

解析1

与前面的二叉树的最大深度、最小深度思路相同,将完全二叉树作为普通二叉树处理,原来的深度换成节点数即可

递归法

class Solution
{
public:
    int countNodes(TreeNode *root)
    {
        return getCount(root);
    }
    int getCount(TreeNode *root)
    {

        int count = 0;
        if (root == NULL)
        {
            return count;
        }
        // 记录左子树的节点个数
        int leftCount = getCount(root->left);
        // 记录右子树的节点个数
        int rightCount = getCount(root->right);
        // 左右子树总的节点个数
        count = leftCount + rightCount + 1;
        return count;
    }
};

image.png

迭代法

class Solution1
{
public:
    int countNodes(TreeNode *root)
    {
        if (root == NULL)
        {
            return 0;
        }
        // 记录总的节点数
        int count = 0;
        queue<TreeNode *> que;
        que.push(root);

        while (!que.empty())
        {
            // 每次遍历时队列中存放的节点数
            int size = que.size();
            // 更新节点数
            count += size;
            for (int i = 0; i < size; i++)
            {
                TreeNode *node = que.front();
                que.pop();
                if (node->left)
                {
                    que.push(node->left);
                }
                if (node->right)
                {
                    que.push(node->right);
                }
            }
        }
        return count;
    }
};

image.png

解析2

完全二叉树有两种情况:满二叉树和非满二叉树

  • 满二叉树:利用公式 2^n -1n表示树的深度
  • 非满二叉树:分别递归其左子树和右子树,递归到某一深度就会有左子树或右子树为满二叉树,然后对其子树按照满二叉树的公式计算节点数

迭代法

class Solution
{
public:
    int countNodes(TreeNode *root)
    {
        if (root == NULL)
        {
            return 0;
        }
        int count = 0;
        TreeNode *leftNode = root->left;
        TreeNode *rightNode = root->right;
        // 定义左右子树的高度
        int leftHeight = 0, rightHeight = 0;
        // 左子树不为空时
        while (leftNode)
        {
            leftNode = leftNode->left;
            leftHeight++;
        }
        // 右子树不为空时
        while (rightNode)
        {
            rightNode = rightNode->right;
            rightHeight++;
        }
        // 如果左子树与右子树的高度相同
        if (leftHeight == rightHeight)
        {
            // 满二叉树的节点个数公式: 2^n - 1
            return (2 << leftHeight) - 1; // 这里的 (2<<1) 表示 2^2 ,因为leftHeight初始为0
        }

        return countNodes(root->left) + countNodes(root->right) + 1;
    }
};

image.png