Given a binary tree, determine if it is height-balanced.
Example 1:
Input: root = [3,9,20,null,null,15,7] Output: true
Example 2:
Input: root = [1,2,2,3,3,null,null,4,4] Output: false
Example 3:
Input: root = [] Output: true
Constraints:
[0, 5000].-104 <= Node.val <= 104The goal of #110 Balanced Binary Tree is to determine whether the height difference between the left and right subtrees of every node is at most one. A straightforward idea is to compute the height of each subtree and verify the balance condition at every node. However, repeatedly calculating subtree heights can lead to unnecessary work.
A more efficient strategy uses Depth-First Search (DFS) with a post-order traversal. Starting from the leaves, compute the height of each subtree and propagate the result upward. If at any node the difference between the left and right subtree heights exceeds one, the tree is not balanced. Many implementations return a special value (for example -1) to signal imbalance and stop further computation early.
This approach ensures each node is visited only once while checking both subtree heights and balance conditions simultaneously. The method is efficient and commonly expected in technical interviews.
| Approach | Time Complexity | Space Complexity |
|---|---|---|
| Naive height check for each node | O(n^2) | O(h) |
| Optimized DFS with post-order traversal | O(n) | O(h) |
take U forward
This approach involves recursively calculating the height of each subtree and checking if the subtrees are balanced by ensuring the difference in height is not more than one.
Time Complexity: O(N^2), where N is the number of nodes in the tree, as we recalculate the height of subtrees multiple times. Space Complexity: O(N) due to recursion stack.
1class TreeNode:
2 def __init__(self, x):
3 self.val = x
4 self.left = None
5 self.right = None
6
7class Solution:
8 def isBalanced(self, root: TreeNode) -> bool:
9 if not root:
10 return True
11
12 def height(node):
13 if not node:
14 return 0
15 return max(height(node.left), height(node.right)) + 1
16
17 left_height = height(root.left)
18 right_height = height(root.right)
19
20 if abs(left_height - right_height) > 1:
21 return False
22
23 return self.isBalanced(root.left) and self.isBalanced(root.right)This Python implementation utilizes a nested helper function height to calculate the height of each node’s subtrees. The primary function isBalanced checks if the balance criteria are satisfied recursively.
This optimized approach calculates the height and balance status of a tree in a single recursive function, thus avoiding recalculations by returning both height and balanced status in form of tuples or objects.
Time Complexity: O(N). Space Complexity: O(N), which includes the recursion stack depth.
1#
Watch expert explanations and walkthroughs
Practice problems asked by these companies to ace your technical interviews.
Explore More ProblemsJot down your thoughts, approach, and key learnings
Yes, this problem or its variations frequently appear in FAANG and other top tech company interviews. It tests understanding of tree traversal, recursion, and how to optimize repeated computations.
The optimal approach uses a depth-first search with post-order traversal. By computing subtree heights while checking the balance condition in the same traversal, each node is processed once, giving O(n) time complexity.
Post-order traversal processes the left and right subtrees before the current node. This makes it ideal for computing subtree heights first and then checking whether the current node satisfies the height-balanced condition.
A binary tree structure combined with recursion or an explicit stack is typically used. DFS traversal works best because it allows you to calculate subtree heights and verify the balance condition during the same pass.
We use a helper struct Result holding both height and balanced state. The checkBalance function recurses over nodes, aggregating this data, and halting early if imbalance is detected.