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