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.
Example 1:

Input: root = [1,2,3,4,5,6] Output: 6
Example 2:
Input: root = [] Output: 0
Example 3:
Input: root = [1] Output: 1
Constraints:
- The number of nodes in the tree is in the range
[0, 5 * 104]. 0 <= Node.val <= 5 * 104- The tree is guaranteed to be complete.
----------------------Solution 2 ----------------------
如果从某节点一直向左的高度 = 一直向右的高度, 那么以该节点为root的子树一定是complete binary tree. 而 complete binary tree的节点数,可以用公式算出 2^h - 1. 如果高度不相等, 则递归调用 return countNode(left) + countNode(right) + 1. 复杂度为O(h^2)
***********上面的是每次查询了最左边和最右边的高度. 还不够好************
******** 3rd pass, 每次对比左右子树的高度 如果相等, 则左边的为full bi nary tree **** 否则,右边的也是full binary tree 但是少了一层*****
上面的需要计算2次高度, 也是浪费。 因为左边的只需要计算一次就可以了
如果从某节点一直向左的高度 = 一直向右的高度, 那么以该节点为root的子树一定是complete binary tree. 而 complete binary tree的节点数,可以用公式算出 2^h - 1. 如果高度不相等, 则递归调用 return countNode(left) + countNode(right) + 1. 复杂度为O(h^2)
public class Solution {
public int countNodes(TreeNode root) {
if(root==null) return 0;
int l = getLeft(root) + 1;
int r = getRight(root) + 1;
if(l==r) {
return (2<<(l-1)) - 1;
} else {
return countNodes(root.left) + countNodes(root.right) + 1;
}
}
private int getLeft(TreeNode root) {
int count = 0;
while(root.left!=null) {
root = root.left;
++count;
}
return count;
}
private int getRight(TreeNode root) {
int count = 0;
while(root.right!=null) {
root = root.right;
++count;
}
return count;
}
}
***********上面的是每次查询了最左边和最右边的高度. 还不够好************
******** 3rd pass, 每次对比左右子树的高度 如果相等, 则左边的为full bi nary tree **** 否则,右边的也是full binary tree 但是少了一层*****
/*** 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)return 0;int hLeft = getHeight(root->left);int hRight = getHeight(root->right);if( hRight == hLeft){ //right child height == left child heightreturn (1<< hLeft) + countNodes(root->right);}else{return (1 << hLeft-1) + countNodes(root->left);}}private:int getHeight(TreeNode* root){ // get height for complete tree, just goes down to the left most nodeif(!root)return 0;return 1 + getHeight(root->left);}};
class Solution {
public:
int countNodes(TreeNode* root) {
return countNodesWithDepth(root, getHeight(root));
}
private:
int countNodesWithDepth(TreeNode* root, int height){
if(!root)
return 0;
if( getHeight(root->right) == height-1){ //right child height == left child height
return (1 << height-1) + countNodesWithDepth(root->right, height-1);
}else{
return (1 << height-2) + countNodesWithDepth(root->left, height-1);
}
}
int getHeight(TreeNode* root){ // get height for complete tree, just goes down to the left most node
if(!root)
return 0;
return 1 + getHeight(root->left);
}
};
但是,理论上是少算了一次,但是LC上并没有速度的改进,反而内存稍微增加了点儿。
Mistakes:
需要用 移位运算, 如果用Math.pow(a,b)的话,会超时
No comments:
Post a Comment