Count Complete Tree Nodes
Given a complete binary tree, count the number of nodes.
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.
Hide Tags
刚开始直接写了个简单的递归,递归计算左右子树,
虽然逻辑上没有问题,但是递归超时
(后来看到有人加了左右相等时直接计算2的幂,可以通过test case)
看题目的提示,是用二分查找,也就是要快速断定最后一个节点的位置。
于是想到就是找root左子的最右边分支,以及右子的最左边分支,
这两个都可以是中点,于是写了一个find函数,找到两个中点,
依照两个中点的深度判断应该选择走左边还是右边。
但是性能并不好,要124ms,把递归调用改成了while循环之后,减少到112ms。
仔细又看了看,实际上并不需要找两个中点,只用右边的就好了,
因为是向左聚拢的嘛,去掉冗余的左边中点,简化判断条件之后,达到了76ms。
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
int countNodes(TreeNode* root)
{
TreeNode* p = root;
int num = 0;
if(root)
{
num = 1;
int hh=0;
while(p)
hh++, p = p->left; //get height
if(1==hh)
return num;
while(root)
{
int hr=0; //find right mid, go right, then keep going left.
p = root->right;
while(p)
hr++, p = p->left;
//last 2nd level
if(2==hh)
return (hr)?((num<<1) +1):(num<<1); //this is why right mid
if((hr==(hh-1))&&(root->right)) //this is why right mid
num = (num<<1)+1, root = root->right; //右子索引=parent*2+1
else if(root->left)
num = (num<<1), root = root->left; //左子索引=parent*2
else
;
hh--;
}
//find(root, hh, num); //recursive call, time-costing.
}
return num;
}
/* ----- ONLY FOR Recursive calls ----- */
void find(TreeNode* root, int hh, int& num)
{
int hl=0, hr=0;
TreeNode* p = root->left;
while(p)
hl++, p = p->right;
p = root->right;
while(p)
hr++, p = p->left;
//last 2nd level
if(2==hh)
{
if(hl&&(!hr))
num = (num<<1);
else
num = (num<<1)+1;
return;
}
if((hr&&(hr==(hh-1)))&&(root->right))
{
num = (num<<1)+1;
return find(root->right, hh-1, num);
}
if(root->left)
{
num = (num<<1)+0;
return find(root->left, hh-1, num);
}
return;
}
/* ----- this solution works but takes too much time ----- */
int countNodes_timeout_solution(TreeNode* root) {
int rst = 0;
if(root)
{
if(root->left)
rst += countNodes(root->left);
if(root->right)
rst += countNodes(root->right);
rst += 1;
}
return rst;
}
};
No comments:
Post a Comment