|
| 1 | +use crate::tree_node::TreeNode; |
| 2 | +use std::cell::RefCell; |
| 3 | +use std::rc::Rc; |
| 4 | + |
| 5 | +/// Given the `root` of a binary tree, the depth of each node is the shortest distance to the root. |
| 6 | +/// |
| 7 | +/// Return the smallest subtree such that it contains all the deepest nodes in the original tree. |
| 8 | +/// |
| 9 | +/// A node is called the deepest if it has the largest depth possible among any node in the entire |
| 10 | +/// tree. |
| 11 | +/// |
| 12 | +/// The subtree of a node is a tree consisting of that node, plus the set of all descenedants of |
| 13 | +/// that node. |
| 14 | +struct Solution; |
| 15 | + |
| 16 | +impl Solution { |
| 17 | + |
| 18 | + fn height(root: &Option<Rc<RefCell<TreeNode>>>) -> usize { |
| 19 | + match root { |
| 20 | + Some(rc) => { |
| 21 | + let node = rc.borrow(); |
| 22 | + let left = Self::height(&node.left); |
| 23 | + let right = Self::height(&node.right); |
| 24 | + let result = 1 + left.max(right); |
| 25 | + result |
| 26 | + } |
| 27 | + None => { |
| 28 | + 0 |
| 29 | + } |
| 30 | + } |
| 31 | + } |
| 32 | + |
| 33 | + fn worker( |
| 34 | + root: &Option<Rc<RefCell<TreeNode>>>, |
| 35 | + height: usize, |
| 36 | + current: usize, |
| 37 | + path: Vec<Option<Rc<RefCell<TreeNode>>>>, |
| 38 | + results: &mut Vec<Vec<Option<Rc<RefCell<TreeNode>>>>> |
| 39 | + ) { |
| 40 | + match root { |
| 41 | + Some(rc) => { |
| 42 | + let node = rc.borrow(); |
| 43 | + let current = current + 1; |
| 44 | + let mut path = path; |
| 45 | + path.push(root.clone()); |
| 46 | + if current == height { |
| 47 | + results.push(path); |
| 48 | + } else { |
| 49 | + Self::worker(&node.left, height, current, path.clone(), results); |
| 50 | + Self::worker(&node.right, height, current, path, results); |
| 51 | + } |
| 52 | + } |
| 53 | + None => { |
| 54 | + // do nothing |
| 55 | + } |
| 56 | + } |
| 57 | + } |
| 58 | + |
| 59 | + pub fn subtree_with_all_deepest(root: Option<Rc<RefCell<TreeNode>>>) -> Option<Rc<RefCell<TreeNode>>> { |
| 60 | + let mut result = None; |
| 61 | + |
| 62 | + let height = Self::height(&root); |
| 63 | + let mut results = Vec::new(); |
| 64 | + Self::worker(&root, height, 0, Vec::new(), &mut results); |
| 65 | + |
| 66 | + let n = results.len(); |
| 67 | + if n == 1 { |
| 68 | + result = results[0][height-1].clone(); |
| 69 | + } else { |
| 70 | + let mut index = 0; |
| 71 | + while index < height { |
| 72 | + let mut done = false; |
| 73 | + let current = results[0][index].clone(); |
| 74 | + for i in 1..n { |
| 75 | + if results[i][index] != current { |
| 76 | + done = true; |
| 77 | + break; |
| 78 | + } |
| 79 | + } |
| 80 | + |
| 81 | + if done { |
| 82 | + break; |
| 83 | + } else { |
| 84 | + result = current; |
| 85 | + index += 1; |
| 86 | + } |
| 87 | + } |
| 88 | + } |
| 89 | + |
| 90 | + result |
| 91 | + } |
| 92 | + |
| 93 | +} |
| 94 | + |
| 95 | +#[cfg(test)] |
| 96 | +mod tests { |
| 97 | + use crate::serialize_and_deserialize_binary_tree::Codec; |
| 98 | + use super::Solution; |
| 99 | + |
| 100 | + #[test] |
| 101 | + fn example_1() { |
| 102 | + let data = "[3,5,1,6,2,0,8,null,null,7,4]".to_string(); |
| 103 | + let codec = Codec::new(); |
| 104 | + let root = codec.deserialize(data); |
| 105 | + let result = Solution::subtree_with_all_deepest(root); |
| 106 | + let items = codec.serialize(result); |
| 107 | + assert_eq!(items, "[2,7,4]"); |
| 108 | + } |
| 109 | + |
| 110 | + #[test] |
| 111 | + fn example_2() { |
| 112 | + let data = "[1]".to_string(); |
| 113 | + let codec = Codec::new(); |
| 114 | + let root = codec.deserialize(data); |
| 115 | + let result = Solution::subtree_with_all_deepest(root); |
| 116 | + let items = codec.serialize(result); |
| 117 | + assert_eq!(items, "[1]"); |
| 118 | + } |
| 119 | + |
| 120 | + #[test] |
| 121 | + fn example_3() { |
| 122 | + let data = "[0,1,3,null,2]".to_string(); |
| 123 | + let codec = Codec::new(); |
| 124 | + let root = codec.deserialize(data); |
| 125 | + let result = Solution::subtree_with_all_deepest(root); |
| 126 | + let items = codec.serialize(result); |
| 127 | + assert_eq!(items, "[2]"); |
| 128 | + } |
| 129 | + |
| 130 | +} |
0 commit comments