use std::rc::Rc; use std::cell::RefCell; #[derive(Debug)] struct TreeNode { val: i32, left: Option<Rc<RefCell<TreeNode>>>, right: Option<Rc<RefCell<TreeNode>>>, } impl TreeNode { fn new(val: i32) -> Rc<RefCell<TreeNode>> { Rc::new(RefCell::new(TreeNode { val, left: None, right: None })) } } struct Solution; impl Solution { fn diameter_of_binary_tree(root: Option<Rc<RefCell<TreeNode>>>) -> i32 { fn depth(node: &Option<Rc<RefCell<TreeNode>>>, max_diameter: &mut i32) -> i32 { if let Some(n) = node { let left_depth = depth(&n.borrow().left, max_diameter); let right_depth = depth(&n.borrow().right, max_diameter); *max_diameter = (*max_diameter).max(left_depth + right_depth); 1 + left_depth.max(right_depth) } else { 0 } } let mut max_diameter = 0; depth(&root, &mut max_diameter); max_diameter } } fn main() { let root = TreeNode::new(1); root.borrow_mut().left = Some(TreeNode::new(2)); root.borrow_mut().right = Some(TreeNode::new(3)); root.borrow_mut().left.as_ref().unwrap().borrow_mut().left = Some(TreeNode::new(4)); root.borrow_mut().left.as_ref().unwrap().borrow_mut().right = Some(TreeNode::new(5)); let diameter = Solution::diameter_of_binary_tree(Some(root)); println!("{}", diameter); }
The diameter is the length of the longest path between any two nodes. Here, the longest path is from node 4 to node 3 passing through nodes 2 and 1, which has length 3 edges.
use std::rc::Rc; use std::cell::RefCell; #[derive(Debug)] struct TreeNode { val: i32, left: Option<Rc<RefCell<TreeNode>>>, right: Option<Rc<RefCell<TreeNode>>>, } impl TreeNode { fn new(val: i32) -> Rc<RefCell<TreeNode>> { Rc::new(RefCell::new(TreeNode { val, left: None, right: None })) } } struct Solution; impl Solution { fn diameter_of_binary_tree(root: Option<Rc<RefCell<TreeNode>>>) -> i32 { fn depth(node: &Option<Rc<RefCell<TreeNode>>>, max_diameter: &mut i32) -> i32 { if let Some(n) = node { let left_depth = depth(&n.borrow().left, max_diameter); let right_depth = depth(&n.borrow().right, max_diameter); *max_diameter = (*max_diameter).max(left_depth + right_depth); 1 + left_depth.max(right_depth) } else { 0 } } let mut max_diameter = 0; depth(&root, &mut max_diameter); max_diameter } } fn main() { let root = TreeNode::new(1); root.borrow_mut().right = Some(TreeNode::new(2)); root.borrow_mut().right.as_ref().unwrap().borrow_mut().right = Some(TreeNode::new(3)); root.borrow_mut().right.as_ref().unwrap().borrow_mut().right.as_ref().unwrap().borrow_mut().right = Some(TreeNode::new(4)); let diameter = Solution::diameter_of_binary_tree(Some(root)); println!("{}", diameter); }
The tree is skewed to the right with nodes 1 -> 2 -> 3 -> 4. The longest path is from node 1 to node 4, which has 3 edges.
use std::rc::Rc; use std::cell::RefCell; #[derive(Debug)] struct TreeNode { val: i32, left: Option<Rc<RefCell<TreeNode>>>, right: Option<Rc<RefCell<TreeNode>>>, } impl TreeNode { fn new(val: i32) -> Rc<RefCell<TreeNode>> { Rc::new(RefCell::new(TreeNode { val, left: None, right: None })) } } struct Solution; impl Solution { fn diameter_of_binary_tree(root: Option<Rc<RefCell<TreeNode>>>) -> i32 { fn depth(node: &Option<Rc<RefCell<TreeNode>>>, max_diameter: &mut i32) -> i32 { if let Some(n) = node { let left_depth = depth(&n.borrow().left, max_diameter); let right_depth = depth(&n.borrow().right, max_diameter); *max_diameter = (*max_diameter).max(left_depth + right_depth); 1 + left_depth.max(right_depth) } else { 0 } } let mut max_diameter = 0; depth(&root, &mut max_diameter); max_diameter } } fn main() { let root = TreeNode::new(1); root.borrow_mut().left = Some(TreeNode::new(2)); root.borrow_mut().left = Some(TreeNode::new(3)); let diameter = Solution::diameter_of_binary_tree(Some(root)); println!("{}", diameter); }
Assigning left child twice overwrites the first child. No mutable borrow conflicts occur because borrows are scoped. The diameter is 2 from node 2 or 3 to 1.
The diameter is the longest path between any two nodes. This path can pass through the current node, connecting the deepest nodes in the left and right subtrees. Hence, we consider left_depth + right_depth at each node.
use std::rc::Rc; use std::cell::RefCell; #[derive(Debug)] struct TreeNode { val: i32, left: Option<Rc<RefCell<TreeNode>>>, right: Option<Rc<RefCell<TreeNode>>>, } impl TreeNode { fn new(val: i32) -> Rc<RefCell<TreeNode>> { Rc::new(RefCell::new(TreeNode { val, left: None, right: None })) } } struct Solution; impl Solution { fn diameter_of_binary_tree(root: Option<Rc<RefCell<TreeNode>>>) -> i32 { fn depth(node: &Option<Rc<RefCell<TreeNode>>>, max_diameter: &mut i32) -> i32 { if let Some(n) = node { let left_depth = depth(&n.borrow().left, max_diameter); let right_depth = depth(&n.borrow().right, max_diameter); *max_diameter = (*max_diameter).max(left_depth + right_depth); 1 + left_depth.max(right_depth) } else { 0 } } let mut max_diameter = 0; depth(&root, &mut max_diameter); max_diameter } } fn main() { let root = TreeNode::new(1); let left = TreeNode::new(2); let right = TreeNode::new(3); let left_left = TreeNode::new(4); let left_right = TreeNode::new(5); let right_right = TreeNode::new(6); let right_right_left = TreeNode::new(7); root.borrow_mut().left = Some(left.clone()); root.borrow_mut().right = Some(right.clone()); left.borrow_mut().left = Some(left_left); left.borrow_mut().right = Some(left_right); right.borrow_mut().right = Some(right_right.clone()); right_right.borrow_mut().left = Some(right_right_left); let diameter = Solution::diameter_of_binary_tree(Some(root)); println!("{}", diameter); }
The longest path is from node 4 to node 7 passing through nodes 2, 1, 3, and 6. This path has 5 edges, so the diameter is 5.
