题目描述
给定两个整数数组 inorder 和 postorder ,其中 inorder 是二叉树的中序遍历, postorder 是同一棵树的后序遍历,请你构造并返回这颗 二叉树 。
示例 1:

输入:inorder = [9,3,15,20,7], postorder = [9,15,7,20,3]
输出:[3,9,20,null,null,15,7]
示例 2:
输入:inorder = [-1], postorder = [-1]
输出:[-1]
提示:
1 <= inorder.length <= 3000postorder.length == inorder.length-3000 <= inorder[i], postorder[i] <= 3000inorder和postorder都由 不同 的值组成postorder中每一个值都在inorder中inorder保证是树的中序遍历postorder保证是树的后序遍历
解题思路


代码
构造新数组
java
/**
* 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 buildTree(int[] inorder, int[] postorder) {
if(inorder == null) return null;
// 在后序数组中找到最后一个元素
int rootVal = postorder[postorder.length - 1];
TreeNode root = new TreeNode(rootVal);
// 已经是叶子结点
if(postorder.length == 1) return root;
// 在中序遍历中找到根节点下标
int indexOfRoot = 0;
for(int i=0; i<inorder.length; i++){
if(inorder[i] == rootVal){
indexOfRoot = i;
break;
}
}
// 切割中序遍历的左右子树
int[] leftInOrder = new int[indexOfRoot];
// 构造左子树中序遍历数组
if(indexOfRoot != 0){
for(int i=0; i<indexOfRoot; i++){
leftInOrder[i] = inorder[i];
}
}else{
leftInOrder = null;
}
// 构造右子树中序遍历数组
int rightSize = inorder.length - indexOfRoot - 1;
int[] rightInOrder = new int[rightSize];
if(rightSize != 0){
for(int i=0; i<rightSize; i++){
rightInOrder[i] = inorder[i+indexOfRoot+1];
}
}else{
rightInOrder = null;
}
// 切割后序遍历的左右子树
int[] leftPostOrder = new int[indexOfRoot];
// 构造左子树后序遍历数组
if(indexOfRoot != 0){
for(int i=0; i<indexOfRoot; i++){
leftPostOrder[i] = postorder[i];
}
}else{
leftPostOrder = null;
}
int[] rightPostOrder = new int[rightSize];
// 构造右子树后序遍历数组
if(rightSize != 0){
for(int i=0; i<rightSize; i++){
rightPostOrder[i] = postorder[i+indexOfRoot];
}
}else{
rightPostOrder = null;
}
TreeNode leftChild = buildTree(leftInOrder, leftPostOrder);
TreeNode rightChild = buildTree(rightInOrder, rightPostOrder);
root.left = leftChild;
root.right = rightChild;
return root;
}
}
记录下标法
java
/**
* 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 buildHelper(int[] inorder, int inorderStart, int inorderEnd, int[] postorder, int postorderStart, int postorderEnd){
if(inorderEnd < inorderStart || postorderEnd < postorderStart) return null;
// 在后序数组中找到最后一个元素
int rootVal = postorder[postorderEnd];
TreeNode root = new TreeNode(rootVal);
// 已经是叶子结点
if(postorderEnd == 0) return root;
// 在中序遍历中找到根节点下标
int indexOfRoot = inorderStart;
for(int i = inorderStart; i <= inorderEnd; i++){
if(inorder[i] == rootVal){
indexOfRoot = i;
break;
}
}
// 切割中序遍历的左右子树
// 构造左子树中序遍历数组
int leftInOrderStart = inorderStart;
int leftInOrderEnd = indexOfRoot - 1;
// 构造右子树中序遍历数组
int rightInOrderStart = indexOfRoot + 1;
int rightInOrderEnd = inorderEnd;
// 切割后序遍历的左右子树
int leftSize = indexOfRoot - inorderStart;
// 构造左子树后序遍历数组
int leftPostOrderStart = postorderStart;
int leftPostOrderEnd = postorderStart + leftSize - 1;
// 构造右子树后序遍历数组
int rightPostOrderStart = postorderStart + leftSize;
int rightPostOrderEnd = postorderEnd - 1;
TreeNode leftChild = buildHelper(inorder, leftInOrderStart, leftInOrderEnd, postorder, leftPostOrderStart, leftPostOrderEnd);
TreeNode rightChild = buildHelper(inorder, rightInOrderStart, rightInOrderEnd, postorder, rightPostOrderStart, rightPostOrderEnd);
root.left = leftChild;
root.right = rightChild;
return root;
}
public TreeNode buildTree(int[] inorder, int[] postorder) {
if(inorder == null) return null;
return buildHelper(inorder, 0, inorder.length - 1, postorder, 0, postorder.length - 1);
}
}
Map记录中序遍历
java
/**
* 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 {
Map<Integer, Integer> map = new HashMap<>();
public TreeNode buildTree(int[] inorder, int[] postorder) {
if(inorder.length == 0) return null;
// 因为每次都需要从先序遍历中找到中间节点进行切分 做成map
for(int i=0; i<inorder.length; i++){
// 值为key 下标为value
map.put(inorder[i],i);
}
return buildHelper(inorder, 0, inorder.length - 1, postorder, 0, postorder.length - 1);
}
// 左闭右闭区间
public TreeNode buildHelper(int[] inorder, int inorderStart, int inorderEnd, int[] postorder, int postorderStart, int postorderEnd){
// 终止条件 数组越界
if(inorderEnd < inorderStart || postorderEnd < postorderStart) return null;
// 在后序数组中找到最后一个元素
int rootVal = postorder[postorderEnd];
TreeNode root = new TreeNode(rootVal);
// 已经是叶子结点
if(postorderEnd == 0) return root;
// 在中序遍历中找到根节点下标
int indexOfRoot = map.get(rootVal);
int leftSize = indexOfRoot - inorderStart;
TreeNode leftChild = buildHelper(inorder, inorderStart, indexOfRoot - 1, postorder, postorderStart, postorderStart + leftSize - 1);
TreeNode rightChild = buildHelper(inorder, indexOfRoot + 1, inorderEnd, postorder, postorderStart + leftSize, postorderEnd - 1);
root.left = leftChild;
root.right = rightChild;
return root;
}
}