We run a preorder depth-first search (DFS) on the root of a binary tree.
At each node in this traversal, we output D dashes (where D is the depth of this node), then we output the value of this node. If the depth of a node is D, the depth of its immediate child is D + 1. The depth of the root node is 0.
If a node has only one child, that child is guaranteed to be the left child.
Given the output traversal of this traversal, recover the tree and return its root.
Example 1:
Input: traversal = “1-2–3–4-5–6–7”
Output: [1,2,5,3,4,6,7]
Example 2:
Input: traversal = “1-2–3—4-5–6—7”
Output: [1,2,5,3,null,6,null,4,null,7]
Example 3:
Input: traversal = “1-401–349—90–88”
Output: [1,401,null,349,88,90]
Constraints:
- The number of nodes in the original tree is in the range [1, 1000].
- 1 <= Node.val <= 109
应该有更优雅的解决方法,但是我是真的想不出来了。
先 left 后 right, 是不是当前节点的直接子节点通过 traversal 中的下一层的 depth 来判断
use std::cell::RefCell;
use std::rc::Rc;
impl Solution {
fn rc(traversal: &mut String, curr_depth: i32) -> Option<Rc<RefCell<TreeNode>>> {
if traversal.is_empty() {
return None;
}
let mut val_str = String::new();
while !traversal.is_empty() {
let c = traversal.remove(0);
if c == '-' {
traversal.insert(0, c);
break;
}
val_str.push(c);
}
let val: i32 = val_str.parse().unwrap();
let mut node = TreeNode::new(val);
let mut next_depth = 0;
while !traversal.is_empty() {
let c = traversal.remove(0);
if c != '-' {
traversal.insert(0, c);
break;
}
next_depth += 1;
}
if next_depth <= curr_depth {
traversal.insert_str(0, "-".repeat(next_depth as usize).as_str());
return Some(Rc::new(RefCell::new(node)));
}
node.left = Solution::rc(traversal, next_depth);
let mut next_depth = 0;
while !traversal.is_empty() {
let c = traversal.remove(0);
if c != '-' {
traversal.insert(0, c);
break;
}
next_depth += 1;
}
if next_depth <= curr_depth {
traversal.insert_str(0, "-".repeat(next_depth as usize).as_str());
return Some(Rc::new(RefCell::new(node)));
}
let right_node = Solution::rc(traversal, next_depth);
node.right = right_node;
Some(Rc::new(RefCell::new(node)))
}
pub fn recover_from_preorder(mut traversal: String) -> Option<Rc<RefCell<TreeNode>>> {
Solution::rc(&mut traversal, 0)
}
}