LeetCode 222 Count Complete Tree Nodes
Given a complete binary tree, count the number of nodes.
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 2h nodes inclusive at the last level h.
which means as left as possible.
and of course we can do it using preorder/in/post/level order
class Solution {
public int countNodes(TreeNode root) {
if (root == null) return 0;
LinkedList<TreeNode> stack = new LinkedList<>();
int count = 0;
stack.push(root);
while (!stack.isEmpty()) {
count++;
TreeNode cur = stack.pop();
if (cur.left != null) stack.push(cur.left);
if (cur.right != null) stack.push(cur.right);
}
return count;
}
}
but clearly that’s not what this problem means, we need to make use of the properties of complete binary tree.
what do you need to know about the complete binary tree is, let’s assume the root is depth of 0 and the maximum depth is d, so the total number of nodes besides the leaf level will be 2^ (d) - 1, and the number of leaves is in the range of (1, 2^d)
and all we need to do is to get the depth, and get the number of nodes in our leave level then we will know. so the number of range will be 1 to 2^d, and we don;t know when the node disappear, so remember something familiar? like find the last 1’s from the int array like [111111110000], so binary search!!! for this problem it’s like [node node node node null null].
//in one word, there is binary search in another binary search
class Solution {
public int countNodes(TreeNode root) {
if (root == null) return 0;
int d = computeDepth(root); //so we compuate the depth first, and we will use this important num to get the range number
if (d == 0) return 1;
int left = 1;
int right = (int)Math.pow(2, d) - 1;
while (left <= right) {
int pivot = left + (right - left) / 2;
if (exists(pivot, d, root)) { //检查第d层第pivot节点是否存在,如果存在 要提升下界
left = pivot + 1;
} else { //否则降低下界
right = pivot - 1;
}
} //after this, the left will be placed at the position of the last node exists
return (int)Math.pow(2, d) - 1 + left; //
}
private int computeDepth(TreeNode root) { //because of the input is a bianry tree so of course you can use this simple way to compute the depth of this tree
int d = 0;
while (root.left != null) {
root = root.left;
d++;
}
return d;
}
private boolean exists(int idx, int d, TreeNode cur) { //就是从root往下面找 如果按照这个index(idx)如果能在第d层里面找到这个节点 说明存在
int left = 0;
int right = (int)Math.pow(2, d) - 1;
for (int i = 0; i < d; i++) { //cur要走d层 直到最底下
int pivot = left + (right - left) / 2;
if (idx <= pivot) { //这儿并没有整明白
cur = cur.left;
right = pivot;
} else {
cur = cur.right;
left = pivot + 1;
}
}
return cur != null;
}
}
虽然长了一些,但是代码总体很清晰,思路也很清晰。

浙公网安备 33010602011771号