Skip to content

Commit 07ba8c0

Browse files
committedFeb 21, 2024
tree travel
1 parent 7597ad5 commit 07ba8c0

File tree

1 file changed

+45
-5
lines changed

1 file changed

+45
-5
lines changed
 

‎src/tree/traversal/no_class.rs

+45-5
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
//! 多种遍历方式混合的
2+
13
use datastructure::TreeNode;
24
use std::cell::RefCell;
35
use std::rc::Rc;
@@ -18,19 +20,46 @@ pub fn build_tree(preorder: Vec<i32>, inorder: Vec<i32>) -> Option<Rc<RefCell<Tr
1820
let root_val = preorder[0];
1921
let mut root = TreeNode::new(root_val);
2022

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

24-
let inorder_left_len = inorder_left.len();
25-
let (preorder_left, preorder_right) = preorder.split_at(inorder_left_len + 1);
26-
27-
root.left = build(&preorder_left[1..], inorder_left);
28-
root.right = build(preorder_right, &inorder_right[1..]);
27+
root.left = build(&preorder[1..1+inorder_left.len()], inorder_left);
28+
root.right = build(&preorder[1+inorder_left.len()..], &inorder_right[1..]);
2929
Some(Rc::new(RefCell::new(root)))
3030
}
3131
build(&preorder, &inorder)
3232
}
3333

34+
/// [106. 从中序与后序遍历序列构造二叉树](https://leetcode.cn/problems/construct-binary-tree-from-inorder-and-postorder-traversal/)
35+
///
36+
/// ## 思路
37+
/// 1. 与[105. 从前序与中序遍历序列构造二叉树](build_tree)类似, 通过中序做分割, 然后递归左右子树
38+
/// 2. 区别是后序遍历的根节点在最后
39+
pub fn build_tree2(inorder: Vec<i32>, postorder: Vec<i32>) -> Option<Rc<RefCell<TreeNode>>> {
40+
fn build(inorder: &[i32], postorder: &[i32]) -> Option<Rc<RefCell<TreeNode>>> {
41+
if postorder.is_empty() {
42+
return None;
43+
}
44+
45+
let root_val = postorder.last().unwrap();
46+
let mut root = TreeNode::new(*root_val);
47+
48+
// 题目保证值不同, 因此可以直接遍历寻找
49+
let root_idx = inorder.iter().position(|&x| x == *root_val).unwrap();
50+
let (inorder_left, inorder_right) = inorder.split_at(root_idx);
51+
52+
root.left = build(inorder_left, &postorder[..inorder_left.len()]);
53+
root.right = build(
54+
&inorder_right[1..],
55+
&postorder[inorder_left.len()..postorder.len() - 1],
56+
);
57+
Some(Rc::new(RefCell::new(root)))
58+
}
59+
60+
build(&inorder, &postorder)
61+
}
62+
3463
#[cfg(test)]
3564
mod tests {
3665
use macros::tree;
@@ -47,4 +76,15 @@ mod tests {
4776
tree!({3, left: {9}, right:{20, left: {15}, right:{7} }})
4877
);
4978
}
79+
80+
#[test]
81+
fn test_build_tree2() {
82+
let inorder = vec![9, 3, 15, 20, 7];
83+
let postorder = vec![9, 15, 7, 20, 3];
84+
let root = build_tree2(inorder, postorder);
85+
assert_eq!(
86+
root,
87+
tree!({3, left: {9}, right:{20, left: {15}, right:{7} }})
88+
);
89+
}
5090
}

0 commit comments

Comments
 (0)