---
# System prepended metadata

title: 222. Count Complete Tree Nodes
tags: [tree, Leetcode, medium, python, c++]

---

###### tags: `Leetcode` `medium` `tree` `python` `c++`

# 222. Count Complete Tree Nodes

## [題目連結:] https://leetcode.com/problems/count-complete-tree-nodes/description/

## 題目:
Given the ```root``` of a **complete** binary tree, return the number of the nodes in the tree.

According to Wikipedia, every level, except possibly the last, is completely filled in a complete binary tree, and all nodes in the last level are as far left as possible. It can have between ``1`` and ```2h``` nodes inclusive at the last level ```h```.

Design an algorithm that runs in less than ```O(n)``` time complexity.

![](https://i.imgur.com/iO4RGWM.png)
![](https://i.imgur.com/DflFZZm.png)

## 解題想法:
* 題目為求complete tree的node總數
    * complete binary tree完全二元樹: 最後一層節點樹不滿
    * Full binary tree完全二元樹: 最後一層滿的
* 先求左右子樹高:
    * 樹高函式getHeight:
        * 一律只往左子樹遞迴計算
    * 若左樹高==右樹高:
        * 則表示左子全滿，右子可能滿or只是complete tree
        * 總數=2 ** 左樹高 +遞迴右子
    * 若高度不相等:
        * 表示左子樹較高(可能為全滿or complete tree)，右子樹較矮(全滿)
        * 總數=2 ** 右樹高 +遞迴左子

## Python:
``` python=
class TreeNode(object):
    def __init__(self, val=0, left=None, right=None):
        self.val = val
        self.left = left
        self.right = right
    def insertLeft(self,node):
        if self.left==None:
            self.left=TreeNode(node)
        else:
            self.left.insertLeft(node)
    def insertRight(self,node):
        if self.right==None:
            self.right=TreeNode(node)
        else:
            self.right.insertRight(node)
    def printTree(self):
        root = self
        que=[root]
        res=[]
        while que:
            curRoot=que.pop(0)
            res.append(curRoot.val)
            if curRoot.left:
                que.append(curRoot.left)
            if curRoot.right:
                que.append(curRoot.right)
        print(res)
        
class Solution(object):
    def countNodes(self, root):
        """
        :type root: TreeNode
        :rtype: int
        """
        #time O(logN * logN)
        if not root:
            return 0
        nodes = 0
        left_height = self.getHeight(root.left)
        right_height = self.getHeight(root.right)
        if left_height==right_height: #若相等 則左子全滿 右子可能滿or只是complete tree
            nodes = 2**left_height + self.countNodes(root.right)
        else: #右子差左子一整層
            nodes = 2**right_height + self.countNodes(root.left)
        return nodes
        
    def getHeight(self,root): #起始根節點高度視為0
        height=0
        tmp=root
        while tmp:
            height+=1
            tmp=tmp.left
        return height

root = TreeNode(1)
root.insertLeft(2)
root.insertRight(3)
root.left.insertLeft(4)
root.left.insertRight(5)
#root.right.insertLeft(6)
root.printTree()

result = Solution()
ans = result.countNodes(root)
print(ans)
```

## C++:
``` cpp=
/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
public:
    int countNodes(TreeNode* root) {
        if (root==nullptr)
            return 0;
        int nodes=0;
        int leftHeight=getHeight(root->left);
        int rightHeight=getHeight(root->right);
        if (leftHeight==rightHeight) //#include <cmath>
            nodes=pow(2,leftHeight)+countNodes(root->right);
        else
            nodes=pow(2,rightHeight)+countNodes(root->left);
        return nodes;
    }

    int getHeight(TreeNode* root){
        int height=0;
        TreeNode* tmp=root;
        while (tmp){
            tmp=tmp->left;
            height+=1;
        }
        return height;
    }
};
```