「这是我参与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;
}
};
迭代法
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;
}
};
解析2
完全二叉树有两种情况:满二叉树和非满二叉树
- 满二叉树:利用公式
2^n -1,n表示树的深度 - 非满二叉树:分别递归其左子树和右子树,递归到某一深度就会有左子树或右子树为满二叉树,然后对其子树按照满二叉树的公式计算节点数
迭代法
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;
}
};