222. Count Complete Tree Nodes

一、题目

  1、审题

  

  2、分析

    求一棵完全二叉树的节点个数。

 

二、解答

  1、思路

    方法一、

      将二叉树将 root 节点分为左右两颗子树。

      ①、若右子树的高度 小于 左子树的高度,则此完全二叉树的最后一个节点落于 左子树,则右子树是一棵高度为 h - 2 的完全二叉树;

        节点数等于 1 << h - 2 + nodes(left);

      ②、若右子树的高度 等于 左子树的高度,则最后一个节点落于右子树,则左子树是一棵高度为 h - 1 的完全二叉树。

        节点数等于 1 << h - 1 + nodes(right)。

 1     public int countNodes(TreeNode root) {
 2      
 3         int h = getHeight(root);    // 根节点的最大高度
 4         
 5         if(h < 1)
 6             return 0;
 7         // 右孩子的最大高度
 8         int rightChildHeight = getHeight(root.right);    
 9         // 完全二叉树的最后一个孩子在 root 的右孩子上, 则 root 左孩子是 高度为 h - 1 的满二叉树
10         if(rightChildHeight == h - 1)
11             return (1 << h - 1) + countNodes(root.right);
12         else
13             // root 右孩子是层次为 n - 2 的满二叉树
14             return   (1 << h - 2) + countNodes(root.left);
15     }
16     
17     // 获得 root 的最大高度
18     private int getHeight(TreeNode root) {
19         return root == null ? 0 : 1 + getHeight(root.left);
20     }

 

  方法二、

    采用循环,每次将所要求得完全二叉树缩小成右子树或左子树;

    不用重复调用方法求 h,h--即可。

 1     public int countNodes(TreeNode root) {
 2         int nodes = 0;
 3         int h = getHeight(root);
 4         while(root != null) {
 5             //最后一个节点在右子树, 左子树是满二叉树
 6             if(getHeight(root.right) == h - 1) { 
 7                 nodes += (1 << h - 1);
 8                 root = root.right;
 9             }
10             else {
11                 nodes += (1 << h - 2);
12                 root = root.left;
13             }
14             h--;
15         }
16         return nodes;
17     }
18     
19     // 获得 root 的最大高度
20     private int getHeight(TreeNode root) {
21         return root == null ? 0 : 1 + getHeight(root.left);
22     }

 

  方法三、

    不用单独求树的高度,采用递归,每次必有左子树或右子树为满二叉树,在递归求另一边非满二叉树即可。

    public int countNodes(TreeNode root) {
        if(root == null)
            return 0;
        
        TreeNode left = root, right = root;
        int height = 0;
        while(right != null) {
            left = left.left;
            right = right.right;
            height++;
        }
        if(left == null)    // 满二叉树
            return (1 << height) - 1;
        return 1 + countNodes(root.left) + countNodes(root.right);
    }

 

posted @ 2018-11-05 21:32  skillking2  阅读(111)  评论(0编辑  收藏  举报