标题:106从中序与后序遍历序列构造二叉树-中等
题目
给定两个整数数组 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 <= 3000
- postorder.length == inorder.length
- -3000 <= inorder[i], postorder[i] <= 3000
- inorder 和 postorder 都由 不同 的值组成
- postorder 中每一个值都在 inorder 中
- inorder 保证是树的中序遍历
- postorder 保证是树的后序遍历
代码Java
// 时效较差,因为使用了很多Arrays方法
public TreeNode buildTree(int[] inorder, int[] postorder) {
// 1. 后序空的话 直接设为null
if (postorder.length == 0) return null;
// 2. 选取后序的最后一个元素 作为本结点的值
int endval = postorder[postorder.length - 1];
TreeNode root = new TreeNode(endval);
// 3. 找到inorder中的切割点
int mid = -1;
for (int i = 0; i < inorder.length; i++) {
if (inorder[i] == endval) {
mid = i;
break;
}
}
// 4. 切割中序
int[] inLeft = Arrays.copyOfRange(inorder, 0, mid);
int[] inRight = Arrays.copyOfRange(inorder, mid + 1, inorder.length);
// 5. 寻找后序
int[] postLeft = Arrays.copyOfRange(postorder, 0, inLeft.length);
int[] postRight = Arrays.copyOfRange(postorder, postLeft.length, postorder.length - 1);
root.left = buildTree(inLeft, postLeft);
root.right = buildTree(inRight, postRight);
return root;
}
public TreeNode buildTree1(int[] inorder, int[] postorder) {
return build(inorder, 0, inorder.length, postorder, 0, postorder.length);
}
// 用双指针代替 Arrays方法
public TreeNode build(int[] inorder, int inLeft, int inRight, int[] postorder, int postLeft, int postRight) {
if (postRight - postLeft < 1) {
return null;
}
// 只有一个元素了
if (inRight - inLeft == 1) {
return new TreeNode(inorder[inLeft]);
}
int endval = postorder[postRight - 1];
TreeNode root = new TreeNode(endval);
int mid = -1;
for (int i = inLeft; i < inRight; i++) {
if (inorder[i] == endval) {
mid = i;
break;
}
}
root.left = build(inorder, inLeft, mid,
postorder, postLeft, postLeft + mid - inLeft);
root.right = build(inorder, mid + 1, inRight,
postorder, postLeft + mid - inLeft, postRight - 1);
return root;
}