根据前序遍历和中序遍历 重建二叉树
题目描述
输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回。
主要思想
递归方法 public TreeNode reConstruct(int[] pre, int preStart, int preEnd, int[] in, int inStart, int inEnd)
preStart 和 preEnd 表示当前根节点中,前序遍历指向左子树或右子树的指针
inStart 和 inEnd 表示中序遍历中的
以题目的输入数据为例,左子树第一层递归中
-
前序遍历传入高亮部分数据: {1,2,4,7,3,5,6,8}
-
中序遍历传入高亮部分数据: {4,7,2,1,5,3,8,6}
递归1
使用for循环获取中序遍历根节点下标
i - inStart表示左孩子的数量
/**
* Definition for binary tree
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
public class Solution {
public TreeNode reConstructBinaryTree(int [] pre,int [] in) {
return reConstruct(pre, 0, pre.length - 1, in, 0, in.length - 1);
}
public TreeNode reConstruct(int[] pre, int preStart, int preEnd, int[] in, int inStart, int inEnd) {
if(preStart > preEnd || inStart > inEnd) {
return null;
}
TreeNode root = new TreeNode(pre[preStart]);
for(int i = 0; i < in.length; i++) {
if(in[i] == pre[preStart]) {
root.left = reConstruct(pre, preStart + 1, preStart + i - inStart, in, inStart, i - 1);
root.right = reConstruct(pre, i - inStart + preStart + 1, preEnd, in, i + 1, inEnd);
break;
}
}
return root;
}
}
递归2
递归1的优化版本
使用HashMap记录中序遍历的值与相应下标,无需使用循环
这种方法使递归的参数结构更加易于理解
/**
* Definition for binary tree
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
import java.util.HashMap;
import java.util.Map;
public class Solution {
public TreeNode reConstructBinaryTree(int [] pre,int [] in) {
Map<Integer, Integer> inMap = new HashMap<Integer, Integer>();
for(int i = 0; i < in.length; i++) {
inMap.put(in[i], i);
}
return reConstruct(pre, 0, pre.length - 1, in, 0, in.length - 1, inMap);
}
public TreeNode reConstruct(int[] pre, int preStart, int preEnd, int[] in, int inStart, int inEnd, Map<Integer, Integer> inMap) {
if(preStart > preEnd) {
return null;
}
int rootVal = pre[preStart];
TreeNode root = new TreeNode(rootVal);
int rootIndex = inMap.get(rootVal);
int leftNum = rootIndex - inStart;
int rightNum = inEnd - rootIndex;
root.left = reConstruct(pre, preStart + 1, preStart + leftNum, in, inStart, rootIndex - 1, inMap);
root.right = reConstruct(pre, preStart + 1 + leftNum, preEnd, in, rootIndex + 1, inEnd, inMap);
return root;
}
}