7 重建二叉树

https://www.nowcoder.com/practice/8a19cbe657394eeaac2f6ea9b0f6fcf6?tpId=13&tqId=11157&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking

 

  考研的时候闭着眼写的题目吭哧了半天……

  首先一个技巧是把中序的数组存成了Map的形式,每次在根据value找到相应下标的时候O(1),空间换时间的方法。

  其次牛客网上的函数的入参是两个数组,这样在递归的时候每次要传不同的数组,就涉及到同一组数据的来回复制,浪费空间,所以重新定义了一个方法,在新定义的方法上递归而不是在题目提供的方法上递归。新的方法的入参包括pre in数组,这两个数组是不变的,在递归的不同时候使用数组里的不同的部分,即start end这四个索引值。

  当然递归最重要的是递归终止的条件,以及递归终止后该返回什么值。在本体中,递归终止意味着用来重建一个节点的左子树or右子树的节点的个数为0,那么此时其相应的左子树or右子树应该返回为null。那么当子树的节点个数为0的时候就是下表索引非法的时候。

/**
 * Definition for binary tree
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */

import java.util.Arrays;
import java.util.HashMap;
public class Solution {
    public TreeNode reConstructBinaryTree(int [] pre,int [] in) {
       if(pre==null || in==null){
           return null;
       }
        
        HashMap<Integer, Integer> map = new HashMap<>();
        for(int i=0; i<in.length; i++){
            map.put(in[i], i);
        }
        
        return reBuild(pre,0,pre.length-1,in,0,in.length-1,map);
    }
    
    public TreeNode reBuild(int[] pre, int preStart, int preEnd, 
                            int[] in, int inStart, int inEnd,
                           HashMap<Integer,Integer> map){
        
        if(preStart>preEnd || inStart>inEnd){
            return null;
        }
        
        //找出根节点在中序里的索引
        int  rootIndex = map.get(pre[preStart]);
        TreeNode root = new TreeNode(pre[preStart]);
        root.left = reBuild(pre,preStart+1,preStart+rootIndex-inStart,
                           in,inStart,rootIndex-1,
                           map);
        root.right = reBuild(pre, preStart+rootIndex-inStart+1,preEnd,
                             in, rootIndex+1,inEnd,
                             map);
        
        return root;
        
    }
}

 

posted @ 2019-02-20 14:44  AshOfTime  阅读(157)  评论(0编辑  收藏  举报