重建二叉树
我们先弄懂一下为什么知道了先序序列和中序序列就能够完成二叉树的重建。
二叉树前序遍历的顺序为:先遍历根节点;随后递归地遍历左子树;最后递归地遍历右子树。
二叉树中序遍历的顺序为:先递归地遍历左子树;随后遍历根节点;最后递归地遍历右子树。
所以说先序序列的第一个就是我们的根节点
我们依据下面的例子画图来理解二叉树重建的过程:
前序遍历 preorder = [3,9,20,15,7]
中序遍历 inorder = [9,3,15,20,7]
从上面我们知道了二叉树的重建过程,我们发现每一个二叉树的建立过程是一样的,多是根据前序序列找到根节点,然后依据中序序列找到其左右子树,然后在到其左右子树上重复上述过程。所以说我们可以用递归的思想。
因为每次需要在中序序列中寻找根节点,所以我们可以建立一个HashMap来提高我们的搜索效率。
import java.util.*;
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
private HashMap<Integer, Integer> indexMap;
public TreeNode buildTree(int[] preorder, int[] inorder) {
indexMap = new HashMap<Integer, Integer>();//map存储中序序列的值与索引
for (int i = 0; i < inorder.length; i++) {
//中序序列的值作为键,序号作为值
indexMap.put(inorder[i], i);
}
return buildTreeCore(preorder, inorder, 0, preorder.length - 1, 0, inorder.length - 1);
}
public TreeNode buildTreeCore(int[] preorder, int[] inorder, int preorder_left, int preorder_right, int inorder_left, int inorder_right) {
if (preorder_left > preorder_right)
return null;
int preorder_root = preorder[preorder_left];//前序遍历的第一个结点就是根节点
int index_root = indexMap.get(preorder_root);//中序遍历中定位根节点
TreeNode root = new TreeNode(preorder_root);//建立根结点
int size_left_subtree = index_root - inorder_left;//左子树的结点个数
//建立根结点的左节点
root.left = buildTreeCore(preorder, inorder, preorder_left + 1, preorder_left + size_left_subtree, inorder_left, index_root - 1);
//建立根结点的右结点
root.right = buildTreeCore(preorder, inorder, preorder_left + size_left_subtree + 1, preorder_right, index_root + 1, inorder_right);
return root;
}
}