给定两个整数数组 preorder
和 inorder
,其中 preorder
是二叉树的先序遍历, inorder
是同一棵树的中序遍历,请构造二叉树并返回其根节点。
今天看这道题目,首先要先搞懂先序遍历和中序遍历的概念,我记得口诀是先序遍历根左右,中序遍历左根右,按照这个规则遍历二叉树,然后把其存储在数组中,现在是反过来,给出已知先序遍历和中序遍历的两个数组,我们需要把这个二叉树构造出来,具体解题思路看代码
class Solution {
Map<Integer, Integer> indexMap;
public TreeNode recursionBuildTree(int[] preorder, int[] inorder, int preorder_left, int preorder_right,
int inorder_left, int inorder_right) {
// 左边界必须小于等于右边界,否则返回null
if (preorder_left > preorder_right) {
return null;
}
// 因为前序遍历是根左右,所以第一个元素就是根节点,获取其value
int preorder_root = preorder_left;
// 有了root的值,那么就可以知道其在中序遍历数组的下标
int inorder_root = indexMap.get(preorder[preorder_root]);
// 中序遍历是左根右,即根节点的左边是左子树的元素,右边是右子树的元素,所以根据根节点的下标可以计算出左子树元素大小
int inorder_left_size = inorder_root - inorder_left;
// 先把根节点构造出来
TreeNode root = new TreeNode(preorder[preorder_root]);
// 利用递归将根节点的左子树构造出来,这里传递的索引都是左子树的区间
root.left = recursionBuildTree(preorder, inorder, preorder_left + 1, preorder_left + inorder_left_size,
inorder_left, inorder_root - 1);
// 利用递归将根节点的右子数构造出来,这里传递的索引都是右子树的区间
root.right = recursionBuildTree(preorder, inorder, preorder_left + inorder_left_size + 1, preorder_right,
inorder_root + 1, inorder_right);
return root;
}
public TreeNode buildTree(int[] preorder, int[] inorder) {
int n = inorder.length;
// 因为是数组结构,要想快速获取某个value的下标则不方便,于是将inorder这个数组元素存储到Map中,便于获取各节点下标
indexMap = new HashMap<Integer, Integer>();
for (int i = 0; i < n; i++) {
indexMap.put(inorder[i], i);
}
return recursionBuildTree(preorder, inorder, 0, n - 1, 0, n - 1);
}
}