Given a binary tree, determine if it is height-balanced.
A height-balanced binary tree is a binary tree in which the depth of the two subtrees of every node never differs by more than one.
Input: root = [3,9,20,null,null,15,7]
Output: true
Tree:
3
/ \
9 20
/ \
15 7
Node 3: |height(left) - height(right)| = |1 - 2| = 1 ✓
Node 9: leaf ✓
Node 20: |1 - 1| = 0 ✓
All nodes balanced → tree is balanced
Input: root = [1,2,2,3,3,null,null,4,4]
Output: false
Tree:
1
/ \
2 2
/ \
3 3
/ \
4 4
Node 2: |height(left) - height(right)| = |3 - 1| = 2 ✗
Tree is NOT balanced
Input: root = []
Output: true
A tree is balanced if:
This naturally fits a recursive pattern where we check balance bottom-up.
This is a Tree DFS + Height Calculation problem with:
Return two pieces of information from each recursive call:
We can encode this efficiently:
Algorithm:
Why this works:
Calculate height at each node and check difference:
isBalanced(root):
if not root: return True
left_height = height(root.left)
right_height = height(root.right)
return abs(left_height - right_height) <= 1 and
isBalanced(root.left) and isBalanced(root.right)
Problem: O(n²) time - recalculates heights
Time: O(n) where n = number of nodes
Space: O(h) where h = height
1class TreeNode {
2 int val;
3 TreeNode left;
4 TreeNode right;
5 TreeNode() {}
6 TreeNode(int val) { this.val = val; }
7 TreeNode(int val, TreeNode left, TreeNode right) {
8 this.val = val;
9 this.left = left;
10 this.right = right;
11 }
12}
13
14class Solution {
15 public boolean isBalanced(TreeNode root) {
16 return checkHeight(root) != -1;
17 }
18
19 private int checkHeight(TreeNode node) {
20 // Base case: null node is balanced with height 0
21 if (node == null) {
22 return 0;
23 }
24
25 // Check left subtree
26 int leftHeight = checkHeight(node.left);
27 if (leftHeight == -1) { // Left subtree unbalanced
28 return -1;
29 }
30
31 // Check right subtree
32 int rightHeight = checkHeight(node.right);
33 if (rightHeight == -1) { // Right subtree unbalanced
34 return -1;
35 }
36
37 // Check if current node is balanced
38 if (Math.abs(leftHeight - rightHeight) > 1) {
39 return -1;
40 }
41
42 // Return height of current subtree
43 return 1 + Math.max(leftHeight, rightHeight);
44 }
45}
46