Skip to content

Commit

Permalink
2024-02-22
Browse files Browse the repository at this point in the history
  • Loading branch information
hxzhao527 committed Feb 22, 2024
1 parent 07ba8c0 commit 31ec97a
Showing 1 changed file with 73 additions and 2 deletions.
75 changes: 73 additions & 2 deletions src/tree/traversal/no_class.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@ pub fn build_tree(preorder: Vec<i32>, inorder: Vec<i32>) -> Option<Rc<RefCell<Tr
let root_idx = inorder.iter().position(|&x| x == root_val).unwrap();
let (inorder_left, inorder_right) = inorder.split_at(root_idx);

root.left = build(&preorder[1..1+inorder_left.len()], inorder_left);
root.right = build(&preorder[1+inorder_left.len()..], &inorder_right[1..]);
root.left = build(&preorder[1..1 + inorder_left.len()], inorder_left);
root.right = build(&preorder[1 + inorder_left.len()..], &inorder_right[1..]);
Some(Rc::new(RefCell::new(root)))
}
build(&preorder, &inorder)
Expand Down Expand Up @@ -60,6 +60,61 @@ pub fn build_tree2(inorder: Vec<i32>, postorder: Vec<i32>) -> Option<Rc<RefCell<
build(&inorder, &postorder)
}

/// [889. 根据前序和后序遍历构造二叉树](https://leetcode.cn/problems/construct-binary-tree-from-preorder-and-postorder-traversal/)
///
/// ## 思路
/// 1. 没有中序时, 结果可以有多种
/// 2. 通过前序找到根节点, 和左子树的根, 通过后序找到右子树的根
/// - 如果两个根相同, 说明只有左子树
/// - 否则, 递归构建左右子树
/// 3. 通过两个根节点的位置做分割
/// 3. 递归结束条件是前序为空
pub fn construct_from_pre_post(
preorder: Vec<i32>,
postorder: Vec<i32>,
) -> Option<Rc<RefCell<TreeNode>>> {
fn build(preorder: &[i32], postorder: &[i32]) -> Option<Rc<RefCell<TreeNode>>> {
if preorder.is_empty() {
return None;
}
let root_val = preorder[0];
let mut root = TreeNode::new(root_val);

if preorder.len() == 1 {
return Some(Rc::new(RefCell::new(root)));
}
if preorder.len() == 2 {
let left_val = preorder[1];
let left = TreeNode::new(left_val);
root.left = Some(Rc::new(RefCell::new(left)));
return Some(Rc::new(RefCell::new(root)));
}

let left_val = preorder[1];
let left_idx_in_postorder = postorder.iter().position(|&x| x == left_val).unwrap();

let right_val = postorder[postorder.len() - 2];
// check
if right_val != left_val {
let right_idx_in_preorder = preorder.iter().position(|&x| x == right_val).unwrap();

root.left = build(
&preorder[1..right_idx_in_preorder],
&postorder[..left_idx_in_postorder + 1],
);
root.right = build(
&preorder[right_idx_in_preorder..],
&postorder[left_idx_in_postorder + 1..postorder.len() - 1],
);
} else {
root.left = build(&preorder[1..], &postorder[..postorder.len() - 1]);
}

Some(Rc::new(RefCell::new(root)))
}
build(&preorder, &postorder)
}

#[cfg(test)]
mod tests {
use macros::tree;
Expand Down Expand Up @@ -87,4 +142,20 @@ mod tests {
tree!({3, left: {9}, right:{20, left: {15}, right:{7} }})
);
}

#[test]
fn test_build_tree3() {
let preorder = vec![1, 2, 4, 5, 3, 6, 7];
let postorder = vec![4, 5, 2, 6, 7, 3, 1];
let root = construct_from_pre_post(preorder, postorder);
assert_eq!(
root,
tree!({1, left: {2, left: {4}, right:{5}}, right:{3, left: {6}, right:{7} }})
);

let preorder = vec![4, 2, 1, 3];
let postorder = vec![3, 1, 2, 4];
let root = construct_from_pre_post(preorder, postorder);
assert_eq!(root, tree!({4, left: {2, left: {1, left: {3}}}}));
}
}

0 comments on commit 31ec97a

Please sign in to comment.