目录
完全二叉树的节点个数
描述
示例 1
示例 2
示例 3
提示
方法:递归优化
描述
给你一棵 完全二叉树 的根节点 root ,求出该树的节点个数。
完全二叉树 的定义如下:在完全二叉树中,除了最底层节点可能没填满外,其余每层节点数都达到最大值,并且最下面一层的节点都集中在该层最左边的若干位置。若最底层为第 h 层,则该层包含 1~?2h?个节点。
示例 1
输入:root = [1,2,3,4,5,6]
输出:6
示例 2
输入:root = []
输出:0
示例 3
输入:root = [1]
输出:1
提示
- 树中节点的数目范围是?
- 题目数据保证输入的树是 完全二叉树
进阶:遍历树来统计节点是一种时间复杂度为 O(n) 的简单解决方案。你可以设计一个更快的算法吗?
方法:递归优化
常规的遍历我们就不写了。
首先我们要知道满二叉树如果层数为n,其节点个数为。我们肯定可以将一个完全二叉树分了几个满二叉树来组成,比如:
利用完全二叉树的性质,本题可以使用更巧妙的写法,我们对当前节点root的左右子树统计高度,左子树高度为left,右子树高度为right,此时有两种情况:
- left==right:此时右子树和左子树层数相同,那么证明左子树为满二叉树,所以我们当前节点root包含的节点数有2^left-1+1+右子树个数,即2^left+右子树个数
- left!=right:此时右子树和左子树层数不同,那么此时右子树一定为满二叉树,因为如果右子树不满的话,左右子树的层数相差会大于1不满足满二叉树的定义,此时root包含的节点数有2^right-1+1+左子树个数,即2^right+右子树个数
class Solution {
public int countNodes(TreeNode root) {
if(root == null) return 0;
int leftDepth = getDepth(root.left);
int rightDepth = getDepth(root.right);
if (leftDepth == rightDepth) {// 左子树是满二叉树(2^leftDepth),右子树不是
return (1 << leftDepth) + countNodes(root.right);// 2^leftDepth其实是(2^leftDepth-1)+1,左子树+根结点
} else {//右子树是满二叉树,左子树不是
return (1 << rightDepth) + countNodes(root.left);
}
}
private int getDepth(TreeNode root) {
int depth = 0;
while (root != null) {
root = root.left;
depth++;
}
return depth;
}
}
|