Binary Trees · 14 of 35
Check if a tree is balanced or not
Check that at every node of a tree, the left side and the right side are about equally tall, never more than one step apart.
- Simple way
- time O(n^2)
room O(h) - Clever way
- time O(n)
room O(h)
The problem, simply
You get a binary tree. The height of a tree is how many nodes you pass on the longest trip from its top down to a leaf. An empty tree has height 0.
The tree is balanced if, at every single node, the height of the left side and the height of the right side differ by at most 1. Answer true or false.
A story to remember it
Picture it
The note under each node is its height. At node 3 the left side has height 0 and the right side has height 2. That gap of 2 makes the whole tree unbalanced.
- rejected
Examples
Balanced
- In
[1, 2, 3, 4, 5, null, 6, 7]- Out
true
At every node the two sides differ by 0 or 1. For example, at the root the left side has height 3 and the right side has height 2.
One lopsided node
- In
[1, 2, 3, 4, 5, null, 6, null, null, null, null, null, 7]- Out
false
Node 3 has nothing on the left and two nodes stacked on the right.
The root looks fine but is not
- In
[1, 2, 2, 3, null, null, 3, 4, null, null, 4]- Out
false
At the root both sides have height 3, so the root is fine. But each 2 has height 2 on one side and 0 on the other. Every node must be checked, not only the root.
Two nodes
- In
[1, 2]- Out
true
The sides have heights 1 and 0. A gap of 1 is allowed.
Empty tree
- In
[]- Out
true
An empty tree is balanced.
Way 1: the simple way
At every node, measure the height of the left side and the right side from scratch, and check the gap. Then do the same for both children.
- If the node is empty, it is balanced.
- Measure
height(left)andheight(right). If they differ by more than 1, answerfalse. - Otherwise check the left child and the right child the same way.
class Solution {
public boolean isBalanced(TreeNode root) {
if (root == null) return true;
int gap = Math.abs(height(root.left) - height(root.right));
return gap <= 1 && isBalanced(root.left) && isBalanced(root.right);
}
private int height(TreeNode n) {
if (n == null) return 0;
return 1 + Math.max(height(n.left), height(n.right));
}
}How long it takes: every node measures everything below it again. In a tree shaped like a long stick that adds up to about n * n / 2 steps, O(n^2). For a balanced tree it is closer to O(n log n). Extra room: the waiting helpers, O(h).
Way 2: the clever way
Measure each height only once, from the bottom up, and check the gap at the same moment. A helper returns the height of its subtree, or -1 if something below is broken.
- An empty spot returns 0.
- Ask the left child. If it says -1, return -1 right away.
- Ask the right child. If it says -1, return -1 right away.
- If the two heights differ by more than 1, return -1.
- Otherwise return
1 + max(left, right).
Heights from the bottom up, with a broken signal
01 / 08
Each helper first asks its children for their heights, so the answers start at the bottom. An empty spot has height 0.
- looking now
- done
- rejected
class Solution {
public boolean isBalanced(TreeNode root) {
return check(root) != -1;
}
// height of this subtree, or -1 if it is not balanced
private int check(TreeNode n) {
if (n == null) return 0;
int left = check(n.left);
if (left == -1) return -1; // broken below: pass it up
int right = check(n.right);
if (right == -1) return -1;
if (Math.abs(left - right) > 1) return -1;
return 1 + Math.max(left, right);
}
}How long it takes: each node is visited once, O(n), and we stop early when we find a broken spot. Extra room: the waiting helpers, O(h), where h is the height. In a stick shaped tree that is O(n).
Watch out for
- Counting edges in one place and nodes in another. Pick one meaning of height and use it everywhere. The gap is the same either way.
- Using -1 as the signal is safe here because a real height is never negative.
- A very tall stick shaped tree can overflow the call stack in Java. Mention an iterative post order walk if the interviewer asks.
What interviewers ask next
- Return the height and the answer together without -1? Return a small pair
{balanced, height}. It reads clearer but does the same work. - What is the tallest a balanced tree with
nnodes can be? About1.44 log2(n). That is why balanced trees (AVL trees) keep search fast. - Make a sorted array into a balanced search tree? Pick the middle as the root and repeat on both halves.
- Same idea, other problems: diameter of a tree and maximum path sum also return a height while tracking a second answer.
Remember this
Grown-up words: the seesaw check is a height balanced test; asking children first is post order traversal; the "broken" shout is a sentinel value; the waiting helpers are the call stack.