根据前序后序遍历求出二叉树
一、题目描述
给定两个整数数组,preorder
和 postorder
,其中 preorder
是一个具有 无重复 值的二叉树的前序遍历,postorder
是同一棵树的后序遍历,重构并返回二叉树。
二、题目分析
- 需求:通过给定
前序+后序
得到二叉树 - 方式:使用计算方式,递归dfs
- 细化:如何根据前序和后序能够推出二叉树,前序遍历与后序遍历的不同点,以及他们能够容易确定的点,比如root节点preorder[0]、左子树第一个节点preorder[1]
- 分树:root+左子树+右子树。左子树的个数=后序遍历到左子树的第一个点的长度,右子树个数=总共个数-左子树个数-1
三、代码
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
public TreeNode constructFromPrePost(int[] preorder, int[] postorder) {
// dfs --前后数组范围--
return dfs(0, preorder.length - 1, 0, postorder.length - 1, preorder, postorder);
}
public TreeNode dfs(int pre_start, int pre_end, int post_start, int post_end, int[] preorder, int[] postorder) {
// 数组下标有变化,判断
if (pre_start > pre_end) return null;
// 增加根节点(作为返回),判断是否只有根
TreeNode root = new TreeNode(preorder[pre_start]);
int len = pre_end - pre_start + 1;
if (len == 1) {
return root;
}
// 计算左子树有多少个,找到遍历后序得到的左子树根值 也就是前序遍历第二个
int index = post_start;
while (index <= post_end && postorder[index] != preorder[pre_start + 1]){
index++;
}
int leftCount = index - post_start + 1;
// 递归,裁定左右子树范围,并连接上root树节点
root.left = dfs(pre_start + 1, pre_start + leftCount, post_start, post_start + leftCount - 1, preorder, postorder);
root.right = dfs(pre_start + leftCount + 1, pre_end, post_start + leftCount, post_end - 1, preorder, postorder);
return root;
}
}