题目地址:
https://leetcode.com/problems/count-complete-tree-nodes/
求complete binary tree的节点个数。可以先求左子树一路向左的深度,以及右子树一路向右的深度。如果两个深度相等,说明树是full binary tree,这时有公式,节点数等于 ,其中 为树的深度。否则必然有前者深度大于后者,这时递归求解左右子树的节点个数,最后整个加总即可。
public class Solution {
public int countNodes(TreeNode root) {
if (root == null) {
return 0;
}
// 求两个子树分别一路向左和向右的深度
int[] heights = height(root);
int hLeft = heights[0] - 1;
int hRight = heights[1] - 1;
// 如果深度相等,说明是满二叉树,直接套公式;否则递归求解
if (hLeft == hRight) {
return (1 << (hLeft + 1)) - 1;
} else {
return 1 + countNodes(root.left) + countNodes(root.right);
}
}
private int[] height(TreeNode root) {
int hL = 0, hR = 0;
TreeNode cur = root;
while (cur != null) {
hL++;
cur = cur.left;
}
cur = root;
while (cur != null) {
hR++;
cur = cur.right;
}
return new int[]{hL, hR};
}
}
class TreeNode {
int val;
TreeNode left, right;
TreeNode(int x) {
val = x;
}
}
空间复杂度
,是树的深度,只需注意到此树高度平衡即可。关于时间复杂度,可以这样考虑:
对于某棵完全二叉树,看最后的一层的叶子分布。如果最后一层刚好有整层的一半个数的叶子,那么很显然原树的左右子树都是完全二叉树,这时候时间复杂度就是
,否则的话,必然存在一边是完全二叉树,另一边不是,所以有递推方程:
所以
。最差的情况是每次向下递归的时候都只有一棵子树是完全二叉树。
算法正确性可以由数学归纳法知道。