4.前中序遍历还原二叉树
思路:
首先要理解如何根据二叉树的前序遍历和中序遍历还原一棵二叉树。
具体还原步骤可分为7步,根据下图来讲解具体的实现步骤:
- 1、先找到前序遍历的第一个节点,也就是根节点root
- 2、在中序遍历中找到root节点的位置
- 3、中序遍历中,root节点的没用到的左边节点,为当前root节点的左子树
- 4、中序遍历中,root节点的没用到的右边节点,为当前root节点的右子树
- 5、回到前序遍历,根据3步骤中找到的左子树,在前序遍历中画出当前root节点的左子树
- 6、回到前序遍历,根据4步骤中找到的右子树,在前序遍历中画出当前root节点的右子树
- 7、继续在root节点的左右子树中找到新的root节点,也就是在划定的范围里的第一个节点,重复以上步骤
接下来根据上面的理解来解决本题:
本题利用HashMap来存储中序遍历中各个节点的值和下标,键key为节点的值val,值value为节点的下标index
- 确定根节点root在前序遍历中的位置,得到root的值为1
- 确定根节点root在中序遍历中的位置,利用map.get(root.val)得到root在中序遍历中的位置为index
- 接下来就是原理中的3,4,5,6,7步骤的实现
代码实现:
import java.util.HashMap;
import java.util.Map;
public class Solution4 {
//首先利用HashMap来存储每个中序遍历的key用来存储节点值,value存储下标
private static Map<Integer,Integer> map = new HashMap<Integer,Integer>();
public TreeNode reConstructBinaryTree(int[] pre,int[] in) {
//如果前序遍历长度和中序遍历长度不等,返回null
if (pre.length != in.length) return null;
//方便找到当前值在中序遍历中的下标
for (int i = 0; i < in.length; i++) {
map.put(in[i], i);
}
//调用辅助函数,重构二叉树
return help(pre, 0, pre.length - 1, in, 0, in.length - 1);
}
/**
*
* @param pre 前序遍历结果集
* @param preLeft 前序遍历中的当前树的起始位置
* @param preRight 当前树的结束位置
* @param in 中序遍历结果集
* @param inLeft 中序遍历中当前树的起始位置
* @param inRight 当前树的结束位置
* @return
*/
public static TreeNode help(int[] pre, int preLeft, int preRight, int[] in, int inLeft, int inRight) {
//一定要设置,防止数组下标越界
if (preLeft > preRight ) {
return null;
}
//构造根节点:前序遍历的第一个节点为根节点
TreeNode root = new TreeNode(pre[preLeft]);
//找到root节点在中序遍历的位置index
int index = map.get(root.val);
//根据得到的index,能得到root左右子树的区间,继续递归循环
root.left = help(pre, preLeft + 1, preLeft + index - inLeft, in, inLeft, index);
root.right = help(pre, preLeft + index - inLeft + 1, preRight, in, index + 1, inRight);
return root;
}
}