use std::collections::VecDeque; #[derive(Debug)] struct TreeNode { val: i32, left: Option<Box<TreeNode>>, right: Option<Box<TreeNode>>, } impl TreeNode { fn new(val: i32) -> Self { TreeNode { val, left: None, right: None } } } fn width_of_binary_tree(root: Option<Box<TreeNode>>) -> usize { if root.is_none() { return 0; } let mut max_width = 0; let mut queue = VecDeque::new(); queue.push_back((root, 0usize)); while !queue.is_empty() { let level_length = queue.len(); let first_index = queue.front().unwrap().1; let mut last_index = first_index; for _ in 0..level_length { let (node_opt, index) = queue.pop_front().unwrap(); if let Some(node) = node_opt { if node.left.is_some() { queue.push_back((node.left.clone(), 2 * index)); } if node.right.is_some() { queue.push_back((node.right.clone(), 2 * index + 1)); } } last_index = index; } max_width = max_width.max(last_index - first_index + 1); } max_width } fn main() { let mut root = Box::new(TreeNode::new(1)); root.left = Some(Box::new(TreeNode::new(2))); root.right = Some(Box::new(TreeNode::new(3))); root.left.as_mut().unwrap().left = Some(Box::new(TreeNode::new(4))); root.right.as_mut().unwrap().right = Some(Box::new(TreeNode::new(5))); let width = width_of_binary_tree(Some(root)); println!("{}", width); }
The maximum width is calculated by tracking the indices of nodes at each level. The widest level here is the last one with nodes 4 and 5, which are at positions 0 and 3 respectively, so width = 3 - 0 + 1 = 4.
Assigning indices as if the tree was complete helps us measure the horizontal distance between nodes, including gaps caused by missing nodes, so we get the true maximum width.
fn width_of_binary_tree(root: Option<Box<TreeNode>>) -> usize {
if root.is_none() {
return 0;
}
let mut max_width = 0;
let mut queue = VecDeque::new();
queue.push_back((root, 0usize));
while !queue.is_empty() {
let level_length = queue.len();
let first_index = queue.front().unwrap().1;
let mut last_index = first_index;
for _ in 0..level_length {
let (node_opt, index) = queue.pop_front().unwrap();
if let Some(node) = node_opt {
if node.left.is_some() {
queue.push_back((node.left.clone(), 2 * index + 1));
}
if node.right.is_some() {
queue.push_back((node.right.clone(), 2 * index + 2));
}
}
last_index = index;
}
max_width = max_width.max(last_index - first_index + 1);
}
max_width
}The indices for left and right children should be 2 * index and 2 * index + 1 respectively. Swapping them causes incorrect width calculation.
Assigning indices simulating a complete tree allows capturing gaps caused by missing nodes, giving the true maximum width.
use std::collections::VecDeque; #[derive(Debug)] struct TreeNode { val: i32, left: Option<Box<TreeNode>>, right: Option<Box<TreeNode>>, } impl TreeNode { fn new(val: i32) -> Self { TreeNode { val, left: None, right: None } } } fn width_of_binary_tree(root: Option<Box<TreeNode>>) -> usize { if root.is_none() { return 0; } let mut max_width = 0; let mut queue = VecDeque::new(); queue.push_back((root, 0usize)); while !queue.is_empty() { let level_length = queue.len(); let first_index = queue.front().unwrap().1; let mut last_index = first_index; for _ in 0..level_length { let (node_opt, index) = queue.pop_front().unwrap(); if let Some(node) = node_opt { if node.left.is_some() { queue.push_back((node.left.clone(), 2 * index)); } if node.right.is_some() { queue.push_back((node.right.clone(), 2 * index + 1)); } } last_index = index; } max_width = max_width.max(last_index - first_index + 1); } max_width } fn main() { let mut root = Box::new(TreeNode::new(1)); root.left = Some(Box::new(TreeNode::new(2))); root.right = Some(Box::new(TreeNode::new(3))); root.left.as_mut().unwrap().right = Some(Box::new(TreeNode::new(4))); root.right.as_mut().unwrap().right = Some(Box::new(TreeNode::new(5))); root.left.as_mut().unwrap().right.as_mut().unwrap().left = Some(Box::new(TreeNode::new(6))); let width = width_of_binary_tree(Some(root)); println!("{}", width); }
The widest level is the last one with nodes at indices 4 and 8, so width = 8 - 4 + 1 = 5.
