Sword Finger Offer07 Problem Solution-Rebuilding Binary Tree

Problem Description

Enter the results of pre-order traversal and mid-order traversal of a binary tree, and please rebuild the binary tree. Assume that the input result of pre-order traversal and middle-order traversal does not contain repeated numbers.

For example, given

前序遍历 preorder = [3,9,20,15,7]
中序遍历 inorder = [9,3,15,20,7]

Return the following binary tree:

    3
   / \
  9  20
    /  \
   15   7
 

limit:

0 <= 节点个数 <= 5000

Problem-solving ideas:

For any tree, the form of preorder traversal is always

[ 根节点, [左子树的前序遍历结果], [右子树的前序遍历结果] ]

That is, the root node is always the first node in the preorder traversal. And the form of in-order traversal is always

[ [左子树的中序遍历结果], 根节点, [右子树的中序遍历结果] ]

As long as we locate the root node in the in-order traversal, then we can know the number of nodes in the left subtree and the right subtree respectively . Since the lengths of the pre-order traversal and the middle-order traversal of the same subtree are obviously the same, we can correspond to the result of the pre-order traversal and locate all the left and right parentheses in the above form.

In this way, we know the results of the pre-order and middle-order traversal of the left subtree, as well as the results of the pre-order and middle-order traversals of the right subtree, we can recursively construct the left subtree and the right subtree, Then connect the two subtrees to the left and right positions of the root node.

When locating the root node in the in-order traversal, a simple method is to directly scan the results of the entire in-order traversal and find the root node, but this is time-complex. We can consider using a hash table to help us locate the root node quickly . For each key-value pair in the hash map, the key represents an element (the value of the node), and the value represents its position in the mid-order traversal. Before the process of constructing a binary tree, we can scan the list traversed in order to construct this hash map. In the subsequent process of constructing the binary tree, we only need O(1) time to locate the root node.

Insert picture description here

class Solution {
    
    
    public int [] preOrder;
    public int [] inOrder;
    Map<Integer,Integer> inorderMaps;
    //参数1:前序遍历的起点,参数2:子树序列长度,参数3:中序遍历序列的起点
    public TreeNode build(int pleft,int len,int ileft){
    
    
        //如果长度小于0,直接返回null
        if(len<=0){
    
    
            return null;
        }
        //如果长度刚好等于1,那么就自己一个结点形成了一棵子树
        if(len==1){
    
    //结点值就等于前序遍历的第一个结点值
            TreeNode p=new TreeNode(preOrder[pleft]);
            p.left=null;
            p.right=null;
            return p;       //返回这棵子树
        }else{
    
    
            //如果长度>1,那么就首先在前序遍历中找到根节点
            int rootValue=preOrder[pleft];
            //然后在中序遍历中定位到根节点
            int inRootIndex=inorderMaps.get(rootValue);
            //创建这个根节点
            TreeNode root=new TreeNode(rootValue);
            //计算左子树长度=中序遍历根节点-当前子树中序遍历的起点
            int leftlen=inRootIndex-ileft;
            //计算右子树长度=总结点数-左子树长度-1
            int rightlen=len-leftlen-1;
            //得到左子树
            root.left=build(pleft+1,leftlen,ileft);
            //得到右子树
            root.right=build(pleft+leftlen+1,rightlen,inRootIndex+1);
            //返回根节点
            return root;
        }
    }
    public TreeNode buildTree(int[] preorder, int[] inorder) {
    
    
        //用哈希值存放中序遍历序列的值和下标
        inorderMaps=new HashMap<Integer,Integer>();
        int n=inorder.length;
        if(n==0){
    
           //如果序列长度为0,返回null
            return null;
        }
        //赋值给全局变量,可不用传参
        preOrder=new int[n];
        inOrder=new int[n];
        for(int i=0;i<n;i++){
    
    
            preOrder[i]=preorder[i];
            inOrder[i]=inorder[i];
        }
        for(int i=0;i<n;i++){
    
    
            inorderMaps.put(inorder[i],i);
        }

        TreeNode root=build(0,n,0);
        return root;
    }
}

Guess you like

Origin blog.csdn.net/qq_39736597/article/details/115029162