Loading

LeetCode222——完全二叉树的结点个数

题目描述


给出一个完全二叉树,求出该树的节点个数。

题目分析


题中给出的二叉树结构如下:

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */

对于一个完全二叉树,可以确定的是,它的任意一个子树必然也是完全二叉树(或是满二叉树(Perfect Binary tree))。
对于某个根节点 \(root\) 来说,先获取其左子树高度 \(left\) 和右子树高度 \(right\)

  • 当其左子树高度 \(left\) 等于其右子树高度 \(right\) 时,其左子树的第 \(left(或 right)\) 层必然已被填满,因为其右子树也已被填入第 \(n\) 层的结点。此时其左子树为满二叉树,结点个数即为 \(2^{left} - 1\),加上当前根节点即 \(2^{left}\) 个,之后对当前根节点的右子树进行递归处理。
  • 当期左子树高度 \(left\) 大于其右子树高度 \(right\) 时,其右子树的第 \(left\) 层必然未被填入任何一个结点,而此时其第 \(right\) 层必然已被填满,因此其右子树此时也必然为满二叉树,结点个数为 \(2^{right} - 1\),加上当前根节点即 \(2^{right}\) 个,之后对其当前根节点的左子树进行递归处理。

代码


class Solution {
    //完全二叉树的任意子树都是完全二叉树(或满二叉树)
    public int countNodes(TreeNode root) {
        if(root == null){
            return 0;
        }
        int left = getLevel(root.left);//求当前根结点的左子树高度
        int right = getLevel(root.right);//求当前根结点的右子树高度
        if(left == right){
            //左子树高度等于右子树高度,说明左子树必然为满二叉树
            //左子树结点个数:2^left - 1,加上当前根节点即为:2^left,再递归对右子树进行处理
            return (1 << left) + countNodes(root.right); 
        }else{
            //左子树高度不等于右子树高度,说明左子树高度必然比右子树高度大1
            //右子树此时也必然是满二叉树
            //右子树结点个数: 2^right - 1,加上当前根节点即为:2^right,再递归左子树进行处理
            return (1 << right) + countNodes(root.left);
        }
    }
    //完全二叉树,求其高度,只需求其左子树高度即可
    public int getLevel(TreeNode node){
        int level = 0;
        while(node != null){
            level ++;
            node = node.left;
        }
        return level;
    }
}
posted @ 2020-11-24 11:35  Icdd  阅读(128)  评论(0)    收藏  举报