222-count-complete-tree-nodes
Question
https://leetcode.com/problems/count-complete-tree-nodes/description/
Given a complete binary tree, count the number of nodes.
Definition of a complete binary tree from Wikipedia:
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 2hnodes inclusive at the last level h.
Example:
Thought Process
- DFS
- We travel the tree to the left and right at the same time
- If the tree is full tree, we can return the (1 << height) - 1, otherwise we need to search the left and right separately and + 1
- Time complexity O((logn)^2), due to half of traversal is skipped and height function is O(logn)
- Space complexity O(logn) due to recursion stack
- Recursion
- At each root, we get the height and its right child, where the height is based on traversal to the left
- If the rightHeight + 1 == height, it means that we have left part completely full (the height function get to travel to the middle of last level), then the count = (1 << (h - 1)) + countNodes(root.right)
- Otherwise, the right part is completely full, so the count = (1 << (h - 2)) + countNodes(root.left)
- Time complexity O((logn)^2)
- Space complexity O(logn) due to recursion
- Iterative
Solution
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
public int countNodes(TreeNode root) {
if (root == null) return 0;
TreeNode left = root, right = root;
int height = 0;
while (right != null) {
left = left.left;
right = right.right;
height++;
}
// the tree is a full tree
if (left == null) return (1 << height) - 1;
else return 1 + countNodes(root.left) + countNodes(root.right);
}
}
class Solution {
public int countNodes(TreeNode root) {
if (root == null) return 0;
int h = getHeight(root);
int rightH = getHeight(root.right);
// left half is complete
if (h == rightH + 1) return (1 << (h - 1)) + countNodes(root.right);
// right half is complete
else return (1 << (h - 2)) + countNodes(root.left);
}
private int getHeight(TreeNode root) {
if (root == null) return 0;
else return 1 + getHeight(root.left);
}
}
class Solution {
public int countNodes(TreeNode root) {
int h = getHeight(root), count = 0;
while (h > 0) {
int rightH = getHeight(root.right);
// left part is complete
if (h == rightH + 1) {
root = root.right;
count += 1 << (h - 1);
} else {
root = root.left;
count += 1 << (h - 2);
}
h--;
}
return count;
}
private int getHeight(TreeNode root) {
if (root == null) return 0;
else return 1 + getHeight(root.left);
}
}