题目要求
实现时间复杂度低于O(N)的解法。
遍历整棵树求节点个数时间复杂度为O(N)。
这里利用了完全二叉树的性质:通过比较左右子树的最左结点的高度来看哪边是满的,然后递归计算。
1.首先遍历左子树最左节点找到二叉树的层数h(头节点在第1层);
2.遍历右子树最左节点看是否在第h层,若在第h层,说明左子树该完全二叉树左子树是满的;否则其右子树是满的,不过叶子节点都在第h-1层;
3.递归计算。
//计算左子树最左节点的层数
public int mostLeftLevel(TreeNode root)
{
if(root == null)
return 0;
return mostLeftLevel(root.left)+1;
}
//递归计算完全二叉树节点个数
public int countNodes(TreeNode root)
{
if(root == null)
return 0;
int left=mostLeftLevel(root.left);
int right=mostLeftLevel(root.right);
if(left == right)//左子树是满的
return (1<<left)+countNodes(root.right);
else //right < left 右子树是满的,且层数少一层
return (1<<right)+countNodes(root.left);
}