题目描述
给你一棵完全二叉树的根节点 root ,求出该树的节点个数。
完全二叉树的定义如下:在完全二叉树中,除了最底层节点可能没填满外,其余每层节点数都达到最大值,并且最下面一层的节点都集中在该层最左边的若干位置。若最底层为第 h 层,则该层包含 1~ 2h 个节点。
输入:root = [1,2,3,4,5,6]
输出:6
思路分析
首先我们能够想到的最简单的方法就是遍历整一颗树,这样我们就可以知道整棵树中有多少个节点了,这种做法的时间复杂度是 O(n)。
但是我们要知道,这是一颗完全二叉树,我们可以根据完全二叉树的性质来做这道题。
第一种情况如上图所示,右子树为满二叉树,它的节点数可以通过公式得出
count = 2 ^ (hight - 1),然后我们再递归遍历左子树得出所有节点即可。
第二种情况如图所示,左子树为满二叉树,它的节点数可以通过公式得出
count = 2 ^ (hight - 1),然后我们再递归遍历右子树得出所有节点即可。
AC 代码
第一种常规解法:
public int count(TreeNode node){
return node == null ? 0 : count(node.left) + count(node.right) + 1;
}
第二种利用完全二叉树性质的解法:
public int countNodes(TreeNode root) {
if(root == null) return 0;
// 获取左子树的高度
int leftHight = treeHight(root.left);
if(leftHight == 0){
return 1;
}
// 获取右子树的高度
int rightHight = treeHight(root.right);
// 如果左子树高度等于右子树高度,说明左子树是满二叉树,此时只需要递归查询右子树的节点数
if(leftHight == rightHight){
return (1 << leftHight) + count(root.right);
} else {
// 如果左子树的高度大于右子树的高度,说明右子树是满二叉树,此时只需要递归查询左子树的节点数
return (1 << rightHight) + count(root.left);
}
}
public int treeHight(TreeNode root){
return root == null ? 0 : treeHight(root.left) + 1;
}
public int count(TreeNode node){
return node == null ? 0 : count(node.left) + count(node.right) + 1;
}
总结
这题主要是考察我们对完全二叉树的性质是否了解,拿到题目时,第一感觉就是直接递归遍历所有节点,但是我们看到完全二叉树时,我们就要思考是否可以利用它的性质,而不是简单的将题目解答即可。
本文正在参与「掘金 2021 春招闯关活动」, 点击查看 活动详情