Skip to content

Commit

Permalink
tree travel
Browse files Browse the repository at this point in the history
  • Loading branch information
hxzhao527 committed Feb 21, 2024
1 parent 7597ad5 commit 07ba8c0
Showing 1 changed file with 45 additions and 5 deletions.
50 changes: 45 additions & 5 deletions src/tree/traversal/no_class.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
//! 多种遍历方式混合的
use datastructure::TreeNode;
use std::cell::RefCell;
use std::rc::Rc;
Expand All @@ -18,19 +20,46 @@ pub fn build_tree(preorder: Vec<i32>, inorder: Vec<i32>) -> Option<Rc<RefCell<Tr
let root_val = preorder[0];
let mut root = TreeNode::new(root_val);

// 题目保证值不同, 因此可以直接遍历寻找
let root_idx = inorder.iter().position(|&x| x == root_val).unwrap();
let (inorder_left, inorder_right) = inorder.split_at(root_idx);

let inorder_left_len = inorder_left.len();
let (preorder_left, preorder_right) = preorder.split_at(inorder_left_len + 1);

root.left = build(&preorder_left[1..], inorder_left);
root.right = build(preorder_right, &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)
}

/// [106. 从中序与后序遍历序列构造二叉树](https://leetcode.cn/problems/construct-binary-tree-from-inorder-and-postorder-traversal/)
///
/// ## 思路
/// 1. 与[105. 从前序与中序遍历序列构造二叉树](build_tree)类似, 通过中序做分割, 然后递归左右子树
/// 2. 区别是后序遍历的根节点在最后
pub fn build_tree2(inorder: Vec<i32>, postorder: Vec<i32>) -> Option<Rc<RefCell<TreeNode>>> {
fn build(inorder: &[i32], postorder: &[i32]) -> Option<Rc<RefCell<TreeNode>>> {
if postorder.is_empty() {
return None;
}

let root_val = postorder.last().unwrap();
let mut root = TreeNode::new(*root_val);

// 题目保证值不同, 因此可以直接遍历寻找
let root_idx = inorder.iter().position(|&x| x == *root_val).unwrap();
let (inorder_left, inorder_right) = inorder.split_at(root_idx);

root.left = build(inorder_left, &postorder[..inorder_left.len()]);
root.right = build(
&inorder_right[1..],
&postorder[inorder_left.len()..postorder.len() - 1],
);
Some(Rc::new(RefCell::new(root)))
}

build(&inorder, &postorder)
}

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

#[test]
fn test_build_tree2() {
let inorder = vec![9, 3, 15, 20, 7];
let postorder = vec![9, 15, 7, 20, 3];
let root = build_tree2(inorder, postorder);
assert_eq!(
root,
tree!({3, left: {9}, right:{20, left: {15}, right:{7} }})
);
}
}

0 comments on commit 07ba8c0

Please sign in to comment.