剑指offer(4)

重建二叉树

Posted by LQ on June 30, 2017

题目描述

输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{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; }
 * }
 */
public class Solution {
    public TreeNode reConstructBinaryTree(int [] pre,int [] in) {
       TreeNode root=new TreeNode(pre[0]);//前序的第一个数定为根  
    	int len=pre.length;  
    	//当只有一个数的时候  
    	if(len==1){  
        	root.left=null;  
        	root.right=null;  
        	return root;  
    	}  
    	//找到中序中的根位置  
    	int rootval=root.val;  
    	int i;  
    	for(i=0;i<len;i++){  
        	if(rootval==in[i])  
            	break;  
    	}  
    	//创建左子树  
    	if(i>0){  
        	int[] pr=new int[i];  
        	int[] ino=new int[i];  
        	for(int j=0;j<i;j++){  
            	pr[j]=pre[j+1];  
        	}  
        	for(int j=0;j<i;j++){  
            	ino[j]=in[j];  
        	}  
        	root.left=reConstructBinaryTree(pr,ino);  
    	}else{  
        	root.left=null;  
    	}  
    	//创建右子树  
    	if(len-i-1>0){  
        	int[] pr=new int[len-i-1];  
        	int[] ino=new int[len-i-1];  
        	for(int j=i+1;j<len;j++){  
            	ino[j-i-1]=in[j];  
            	pr[j-i-1]=pre[j];  
        	}  
        	root.right=reConstructBinaryTree(pr,ino);  
    	}else{  
        	root.right=null;  
    	}  
    	return root;  
    }  
}