Given the root
of a binary tree, return the maximum width of the given tree. The maximum width of a tree is the maximum width among all levels. The width of one level is defined as the length between the end-nodes (the leftmost and rightmost non-null nodes), where the null nodes between the end-nodes that would be present in a complete binary tree extending down to that level are also counted into the length calculation. It is guaranteed that the answer will in the range of a 32-bit signed integer. The number of nodes in the tree is in the range [1, 3000]
. -100 <= Node.val <= 100
For example:
Input: root = [1,3,2,5,3,null,9]
Output: 4
Explanation: The maximum width exists in the third level with length 4 (5,3,null,9).
Input: root = [1,3,2,5,null,null,9,6,null,7]
Output: 7
Explanation: The maximum width exists in the fourth level with length 7 (6,null,null,null,null,null,7).
Can you provide an algorithm to efficiently compute the maximum width of a binary tree?
A brute force approach to solve this problem would involve performing a level-order traversal of the tree. During the level-order traversal, we'd keep track of the leftmost and rightmost non-null nodes at each level. The width of the level would then be the difference between the indices of these two nodes plus one. We would maintain a global maximum width and update it at each level.
However, this approach requires us to store null nodes in the queue to maintain the structure of the complete binary tree, which can be space-consuming, especially for skewed trees.
The optimal approach also involves a level-order traversal, but it leverages the property of a complete binary tree to assign indices to nodes implicitly. The root node gets index 0. If a node has index i
, its left child gets index 2*i
, and its right child gets index 2*i + 1
. This allows us to track the leftmost and rightmost indices at each level without actually storing the null nodes.
import java.util.LinkedList;
import java.util.Queue;
class TreeNode {
int val;
TreeNode left;
TreeNode right;
TreeNode() {}
TreeNode(int val) { this.val = val; }
TreeNode(int val, TreeNode left, TreeNode right) {
this.val = val;
this.left = left;
this.right = right;
}
}
class Solution {
public int widthOfBinaryTree(TreeNode root) {
if (root == null) {
return 0;
}
Queue<Pair<TreeNode, Integer>> queue = new LinkedList<>();
queue.offer(new Pair<>(root, 0));
int maxWidth = 0;
while (!queue.isEmpty()) {
int size = queue.size();
int left = queue.peek().getValue();
int right = 0;
for (int i = 0; i < size; i++) {
Pair<TreeNode, Integer> current = queue.poll();
TreeNode node = current.getKey();
int index = current.getValue();
if (i == size - 1) {
right = index;
}
if (node.left != null) {
queue.offer(new Pair<>(node.left, 2 * index));
}
if (node.right != null) {
queue.offer(new Pair<>(node.right, 2 * index + 1));
}
}
maxWidth = Math.max(maxWidth, right - left + 1);
}
return maxWidth;
}
static class Pair<K, V> {
private final K key;
private final V value;
public Pair(K key, V value) {
this.key = key;
this.value = value;
}
public K getKey() {
return key;
}
public V getValue() {
return value;
}
}
}