题目描述
输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回。
思路:
通常树有如下几种遍历方式:
前序遍历:先访问根结点,再访问左子结点,最后访问右子结点。
中序遍历:先访问左子结点,再访问根结点,最后访问右子结点。
后序遍历:先访问左子结点,再访问右子结点,最后访问根结点。
本题为前序遍历和中序遍历,最少需要两种遍历方式,才能重建二叉树。
前序遍历序列中,第一个数字总是树的根结点的值。在中序遍历序列中,根结点的值在序列的中间,左子树的结点的值位于根结点的值的左边,而右子树的结点的值位于根结点的值的右边。剩下的我们可以递归来实现,具体如图:
同样的对于左子树,前序遍历确定左子树的根节点,,递归实现
/** * Definition for binary tree *
public class TreeNode { *
int val; *
TreeNode left; *
TreeNode right; *
TreeNode(int x) { val = x; } *
} */
import java.util.Arrays;
public class Solution {
public TreeNode reConstructBinaryTree(int [] pre,int [] in) {
if(pre == null || in == null || pre.length <=0 || in.length <= 0 || pre.length != in.length)
return null;
int len = pre.length;
TreeNode head = new TreeNode(pre[0]);
int headin= 0;
for(int i =0; i <len; i++) {
if(in[i] == pre[0]) {
headin = i;
break; } }
head.left =reConstructBinaryTree(Arrays.copyOfRange(pre,1,headin+1),
Arrays.copyOfRange(in,0,headin));
head.right = reConstructBinaryTree(Arrays.copyOfRange(pre,headin+1,len),
Arrays.copyOfRange(in,headin+1,len));
return head;
}
}
思路二:
整体思路和一是相同的,但是引入了HashMap,相较于思路一是遍历数组,思路二则是根据HashMap的键值对进行查找根节点,复杂度降低。
/**
* 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) {
if(pre==null||in==null){
return null;
}
java.util.HashMap<Integer,Integer> map= new java.util.HashMap<Integer, Integer>();
for(int i=0;i<in.length;i++){
map.put(in[i],i);
}
return preIn(pre,0,pre.length-1,in,0,in.length-1,map);
}
public TreeNode preIn(int[] p,int pi,int pj,int[] n,int ni,int nj,java.util.HashMap<Integer,Integer> map){
if(pi>pj){
return null;
}
TreeNode head=new TreeNode(p[pi]);
int index = map.get(p[pi]);
head.left=preIn(p,pi+1,pi+index-ni,n,ni,index-1,map);
head.right=preIn(p,pi+index-ni+1,pj,n,index+1,nj,map);
return head;
}
}