根据前序和后序遍历构造二叉树
难度:
标签:
题目描述
给定两个整数数组,preorder
和 postorder
,其中 preorder
是一个具有 无重复 值的二叉树的前序遍历,postorder
是同一棵树的后序遍历,重构并返回二叉树。
如果存在多个答案,您可以返回其中 任何 一个。
示例 1:
输入:preorder = [1,2,4,5,3,6,7], postorder = [4,5,2,6,7,3,1] 输出:[1,2,3,4,5,6,7]
示例 2:
输入: preorder = [1], postorder = [1] 输出: [1]
提示:
1 <= preorder.length <= 30
1 <= preorder[i] <= preorder.length
preorder
中所有值都 不同postorder.length == preorder.length
1 <= postorder[i] <= postorder.length
postorder
中所有值都 不同- 保证
preorder
和postorder
是同一棵二叉树的前序遍历和后序遍历
代码结果
运行时间: 20 ms, 内存: 16.2 MB
/*
* The problem is to construct a binary tree from given preorder and postorder traversals using Java Streams.
* We will use a helper function that takes indices of the current subarray in preorder and postorder arrays.
* Using the properties of preorder and postorder traversal, we will recursively construct the tree.
*/
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
class TreeNode {
int val;
TreeNode left;
TreeNode right;
TreeNode(int x) { val = x; }
}
public class Solution {
private int preIndex = 0;
private int[] preorder;
private int[] postorder;
private Map<Integer, Integer> postIndexMap;
public TreeNode constructFromPrePost(int[] preorder, int[] postorder) {
this.preorder = preorder;
this.postorder = postorder;
this.postIndexMap = IntStream.range(0, postorder.length)
.boxed()
.collect(Collectors.toMap(i -> postorder[i], i -> i));
return buildTree(0, postorder.length - 1);
}
private TreeNode buildTree(int left, int right) {
if (left > right || preIndex >= preorder.length) {
return null;
}
TreeNode root = new TreeNode(preorder[preIndex++]);
if (left == right || preIndex >= preorder.length) {
return root;
}
int postIndex = postIndexMap.get(preorder[preIndex]);
root.left = buildTree(left, postIndex);
root.right = buildTree(postIndex + 1, right - 1);
return root;
}
}
解释
方法:
这个题解使用递归的方法来构建二叉树。主要思路是根据前序遍历和后序遍历的特点,找到根节点和左右子树的范围,递归地构建左右子树。具体来说:
1. 前序遍历的第一个元素是根节点
2. 在后序遍历中找到前序遍历第二个元素的位置,可以得到左子树的大小
3. 根据左子树大小,可以确定前序遍历和后序遍历中左右子树的范围
4. 递归地构建左子树和右子树
5. 返回根节点
时间复杂度:
O(n)
空间复杂度:
O(n)
代码细节讲解
🦆
在构建二叉树的过程中,递归函数的终止条件是前序遍历的左指针大于右指针,这是为什么?
▷🦆
题解中提到可以返回任何一个有效的二叉树,这是否意味着前序和后序遍历序列可能对应多个不同的二叉树结构?如果是,能否给出一个具体的例子?
▷🦆
在递归构建二叉树时,如何确保每次递归调用正确无误地分割左右子树?
▷🦆
哈希表`postorder_index`的作用是什么,在解题过程中它如何帮助提高效率?
▷