完全二叉树的节点个数
难度:
标签:
题目描述
给你一棵 完全二叉树 的根节点 root
,求出该树的节点个数。
完全二叉树 的定义如下:在完全二叉树中,除了最底层节点可能没填满外,其余每层节点数都达到最大值,并且最下面一层的节点都集中在该层最左边的若干位置。若最底层为第 h
层,则该层包含 1~ 2h
个节点。
示例 1:

输入:root = [1,2,3,4,5,6] 输出:6
示例 2:
输入:root = [] 输出:0
示例 3:
输入:root = [1] 输出:1
提示:
- 树中节点的数目范围是
[0, 5 * 104]
0 <= Node.val <= 5 * 104
- 题目数据保证输入的树是 完全二叉树
进阶:遍历树来统计节点是一种时间复杂度为 O(n)
的简单解决方案。你可以设计一个更快的算法吗?
代码结果
运行时间: 80 ms, 内存: 21.7 MB
// 思路:我们可以使用Java Stream来实现遍历树的节点并统计个数。我们可以通过递归收集所有节点到一个列表中,然后使用stream的count方法来统计个数。
import java.util.*;
import java.util.stream.*;
public class Solution {
public int countNodes(TreeNode root) {
if (root == null) {
return 0;
}
List<TreeNode> nodes = new ArrayList<>();
collectNodes(root, nodes);
return (int) nodes.stream().count();
}
private void collectNodes(TreeNode node, List<TreeNode> nodes) {
if (node != null) {
nodes.add(node);
collectNodes(node.left, nodes);
collectNodes(node.right, nodes);
}
}
}
// TreeNode是树节点的类定义,假设如下:
class TreeNode {
int val;
TreeNode left;
TreeNode right;
TreeNode(int x) { val = x; }
}
解释
方法:
该题解采用了递归的思路,利用完全二叉树的性质来优化计算节点个数的过程。首先通过 get_height 函数递归计算完全二叉树的高度。如果高度小于等于1,直接返回高度作为节点个数。否则,通过判断右子树的高度是否等于总高度减2,如果是,说明左子树是一个满二叉树,可以直接计算左子树的节点数,再加上右子树递归计算的节点数;如果右子树高度不等于总高度减2,说明右子树是一个满二叉树,可以直接计算右子树的节点数,再加上左子树递归计算的节点数。通过这样的方式,可以避免遍历整棵树,从而降低时间复杂度。
时间复杂度:
O((log n)^2)
空间复杂度:
O(log n)
代码细节讲解
🦆
在递归函数`get_height`中,为什么只计算左子树的高度,而不是同时考虑左右子树的高度?
▷🦆
递归计算高度时的基准情况是什么?即在`get_height`函数中,当什么条件满足时返回0?
▷🦆
在判断右子树的高度是否等于总高度减2时,这种条件判断对于完全二叉树的结构有何重要意义?
▷🦆
题解中使用的`(1 << (height - 2))`和`(1 << (height - 1))`分别是如何计算满二叉树的节点数的?
▷