题目描述:
给你一棵 完全二叉树 的根节点 root ,求出该树的节点个数。
完全二叉树 的定义如下:在完全二叉树中,除了最底层节点可能没填满外,其余每层节点数都达到最大值,并且最下面一层的节点都集中在该层最左边的若干位置。若最底层为第 h 层,则该层包含 1~ 2h 个节点。
来源:力扣(LeetCode)
思路:
1)普通二叉树的 迭代和递归!
递归类似于二叉树的最大最小深度!
2)利用完全二叉树的性质!
完全二叉树:是一棵空树或者叶子节点只出现在后两层的二叉树(也就是只能最后一层不满!);而且如果最后一层不满,叶子节点在左侧。
使用完全二叉树的性质!
3)位运算:2^N最快的计算方法,就是左移一位! 1<<N ;而log2N,右移?
代码:
1)普通二叉树迭代和递归的实现形式:
class Solution {
public int countNodes(TreeNode root) {
//1.迭代法
if(root == null) return 0;
Queue<TreeNode> queue = new LinkedList<>();
queue.offer(root);
int num = 0;
while(!queue.isEmpty()){
int size = queue.size();
for(int i = 0;i < size;i++){
num++;
TreeNode node = queue.poll();
if(node.left != null) queue.offer(node.left);
if(node.right != null) queue.offer(node.right);
}
}
return num;
//2.递归
//分别计算左右子树的 节点个数,并且加上当前节点的1,类似于最大最小深度问题
if(root == null) return 0;
else{
int left = countNodes(root.left);
int right = countNodes(root.right);
return left + right + 1;
}
}
}
2)完全二叉树:
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){
return (1<<leftDepth) + countNodes(root.right);//递归去拿右子树的个数
}else{
return (1<<rightDepth) + countNodes(root.left);
}
}
//完全二叉树,只有最后一层不满!
//造成的结果就是,root的左子树满,右子树不满;或者右子树满,左子树不满!
int getDepth(TreeNode root){
if(root == null) return 0;
else return Math.max(getDepth(root.left),getDepth(root.right)) + 1;
}
}
最大深度一定是最左边节点的深度:
int getDepth(TreeNode root){
int depth = 0;
while(root != null){
depth++;
root = root.left;
}
return depth;
}