- 利用先序和中序遍历结果数组 pre 和 in,重建二叉树
- 首先考虑初始情况,即两个初始数组 pre,in
pre[0]
作为先序遍历的第一个节点,也是树根节点,把 in 划分为左右子树两个区间inleft 和 inright
- 根据 in 中 pre[0] 的
下标
,把 pre 数组同样划分为,左右子树的前序遍历的两个区间preleft 和 preright
- 递归重建和划分,直到 pre 和 in 数组为长度为 0
- 比如,pre = [
1
2 3 4 5 6 7], in = [3 2 41
6 5 7],pre[0] = 1 为树根节点 - pre[0] 划分 in 为
左右子树的中序遍历数组
:inleft = [3 2 4
], inright = [6 5 7
],pre[0] 在 in 的下标为 i = 3 - 找 inleft 和 inright 在 pre 中的
对应区间
:preleft = [2 3 4
],preright = [5, 6, 7
] - 递归此过程
java 代码
import java.util.Arrays;
public class Solution {
public TreeNode reConstructBinaryTree(int [] pre,int [] in) {
// pre = [1 2 3 4 5 6 7], in = [3 2 4 1 6 5 7]
if (pre.length == 0 || in.length == 0) return null;
// 每次用 pre[0] 创建树根节点,第一次为 1
TreeNode root = new TreeNode(pre[0]);
// 查找 pre[0] 在 in 数组中的下标,用于后续划分 pre 和 in 数组
int i = getRootIndex(in, pre[0]); // i = 3
// 在 in 数组中,截取左子树的中序遍历数组 inleft = [3 2 4]
int[] inleft = Arrays.copyOfRange(in, 0, i);
// 在 pre 数组中,截取 inleft 对应的先序遍历数组 preleft = [2 3 4]
int[] preleft = Arrays.copyOfRange(pre, 1, i + 1); // 除开 pre[0], 下标整体加 1
// 递归构建 root 左子树
root.left = reConstructBinaryTree(preleft, inleft);
// 在 in 数组中,截取右子树的中序遍历数组 inright = [6 5 7]
int[] inright = Arrays.copyOfRange(in, i, in.length);
// 在 pre 数组中,截取 inright 对应的前序遍历数组 preright = [5 6 7]
int[] preright = Arrays.copyOfRange(pre, i + 1, pre.length);
// 递归构建 root 右子树
root.right = reConstructBinaryTree(preright, inright);
// 返回 root 节点
return root;
}
public int getRootIndex(int[] in, int root) {
for (int i = 0; i < in.length; i++) {
if (in[i] == root) return i;
}
return 0;
}
}
- 总结:递归的关键是,每次都要找出
当前子树下对应的 pre 和 in