問題描述:
Share
Given a complete binary tree, count the number of nodes.
Note:
Definition of a complete binary tree from Wikipedia:
In a complete binary tree every level, except possibly the last, is completely filled, and all nodes in the last level are as far left as possible. It can have between 1 and 2hnodes inclusive at the last level h.
Example:
Input: 1 / \ 2 3 / \ / 4 5 6 Output: 6
源碼:
最簡單的肯定就是遞歸,但是這樣完全沒有用到完全二叉樹的特性,肯定不是最佳的。
class Solution {
public:
int countNodes(TreeNode* root) {
if (!root) return 0;
return countNodes(root->left) + countNodes(root->right) + 1;
}
};
翻了一下別人的博客,有一種優化方案,其實我感覺也不優化,完全是爲了用上而用上條件。就是如果一棵子樹的最左邊的長度等於右邊的長度,就直接返回2^l-1,這樣省去了遍歷的步驟,但是這完全是一種“豪賭”,如果不滿足條件,損耗會更大。
class Solution {
public:
int countNodes(TreeNode* root) {
if ( !root ) return 0;
int hl = 1;
TreeNode* l = root->left;
int hr = 1;
TreeNode* r = root->right;
while ( l ){
++hl;
l = l->left;
}
while ( r ){
++hr;
r = r->right;
}
if ( hr==hl ) return pow(2, hr)-1;
return Solution::countNodes(root->left) + Solution::countNodes(root->right) + 1;
}
};
還有一種類似於二分查找的算法,很牛皮,首先我們需要一個depth函數用來計算最大高度,若當前結點不存在,則返回 -1。我們對當前結點調用 depth函數,若爲 -1,則說明當前結點不存在,直接返回0。否則就對右子結點調用depth 函數,若返回值爲 d-1,說明左子樹是一棵完美二叉樹,再加上當前結點,總共是 2^hd個,即 1<<d,若對右子結點調用 depth 函數的返回值不爲 d-1,說明右子樹一定是完美樹,加上當前結點爲 2^(d-1),即 1<<(d-1)
class Solution {
public:
int depth(TreeNode* root){
return root ? (1+depth(root->left)) : -1;
}
int countNodes(TreeNode* root) {
int d = depth(root);
if(d == -1) return 0;
cout<<d<<endl;
if (depth(root->right) == d-1) return countNodes(root->right) + (1<<d);
return (1<<(d-1)) + countNodes(root->left);
}
};