树与图简单2 种解法
#222完全二叉树的节点个数
统计一棵完全二叉树的节点总数。
#完全二叉树#深度优先搜索#广度优先搜索
原题
给你一棵 完全二叉树 的根节点 root ,求出该树的节点个数。
完全二叉树 的定义如下:在完全二叉树中,除了最底层节点可能没填满外,其余每层节点数都达到最大值,并且最下面一层的节点都集中在该层最左边的若干位置。若最底层为第 h 层(从第 0 层开始),则该层包含 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) 的简单解决方案。你可以设计一个更快的算法吗?
解题主线
- 普通遍历适用于所有二叉树,也自然适用于完全二叉树。
解法 1:递归计数
节点总数等于左子树节点数加右子树节点数再加一。
-
时间复杂度: O(n)
-
空间复杂度: O(h)
import java.util.*;
class TreeNode {
int val;
TreeNode left;
TreeNode right;
TreeNode(int val) {
this.val = val;
}
}
class Solution {
public int countNodes(TreeNode root) {
// 空子树贡献零个节点,也是递归终止条件。
if (root == null) return 0;
// 当前子树节点数由左右子树计数与根节点共同组成。
return countNodes(root.left) + countNodes(root.right) + 1;
}
}解法 2:BFS 计数
每个节点出队时计数并加入其非空孩子。
-
时间复杂度: O(n)
-
空间复杂度: O(w)
import java.util.*;
class TreeNode {
int val;
TreeNode left;
TreeNode right;
TreeNode(int val) {
this.val = val;
}
}
class Solution {
public int countNodes(TreeNode root) {
if (root == null) return 0;
Deque<TreeNode> queue = new ArrayDeque<>();
queue.offer(root);
int count = 0;
// 队列中始终保存已发现但尚未计数的节点。
while (!queue.isEmpty()) {
TreeNode node = queue.poll();
count++;
// 只将非空孩子入队,确保每个节点恰好计数一次。
if (node.left != null) queue.offer(node.left);
if (node.right != null) queue.offer(node.right);
}
return count;
}
}边界与易错点
- 队列计数不需要按层,但保留分层也不会影响正确性。
整理来源
由旧仓库源码复核、去重并整理;展示代码已按 Java 21 语义修正明显问题。
leetcode/src/main/java/tree/Q222_countNodes.java