7. Rebuild the Binary Tree

Jianzhi offer 07 Rebuild the binary tree

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 traversal preorder = [3,9,20,15,7] Inorder
traversal inorder = [9,3,15,20,7]

Return the following binary tree:

    3
   / \
  9  20
    /  \
   15   7

limit:

0 <= number of nodes <= 5000 0 <= number of nodes <= 5000 0<=Section point a number<=5000

注意:This question is the same as the 105 question of the main site: https://leetcode-cn.com/problems/construct-binary-tree-from-preorder-and-inorder-traversal/

前置知识:If there are repeated numbers, the pre-order and middle-order cannot determine a binary tree, because the repeated numbers in the pre-order sequence correspond to which of the same repeated numbers in the middle-order sequence, which makes it impossible to judge the left and right nodes in the current pre-order sequence. node.

Problem-solving ideas

The first value of the preorder traversal is the value of the root node. Use this value to divide the middle order traversal result into two parts. The left part is the left subtree middle order traversal result of the tree, and the right part is the right subtree middle order traversal result of the tree. the result of. Then the left and right subtrees are solved recursively.

  • First use HashMapto inordersave the sequence ( the index position of the key:node's val value:node in the sequence), and then HashMapfind inorderthe position of the root node in the sequence according to it.
  • The root node valin HashMapthe root node is a value corresponding inorderposition in the sequence.
  • Then the tree can be built recursively according to the number of nodes on the left and right sides of the root node in the middle order.
    Insert picture description here

Java code

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
class Solution {
    
    
    public TreeNode buildTree(int[] preorder, int[] inorder) {
    
    
        if(preorder==null || preorder.length==0) return null;//preorder.length==0的话,inorder.length肯定也为0,所以只判断一个即可
        HashMap<Integer ,Integer> hashmap = new HashMap<>();
        for(int i = 0;i<inorder.length;i++){
    
    //将中序的信息存入HashMap,方便后面根据根节点分割左右子树
            hashmap.put(inorder[i],i);
        }
        return dfs(preorder,0,preorder.length-1,0,hashmap);
    }
    
    //pl即preorder left,即前序数组的左边界,pr即前序数组的右边界,同理il即中序的左边界
    public TreeNode dfs(int[] preorder,int pl,int pr,int il,HashMap<Integer ,Integer> hashmap){
    
    
        if(pl>pr) return null;//递归终止条件,前序数组中没有元素了
        TreeNode curRoot = new TreeNode(preorder[pl]);//当次递归的根节点
        int k = hashmap.get(curRoot.val);//当前根节点在中序数组中的索引
        curRoot.left = dfs(preorder,pl+1,pl+(k-il),il,hashmap); //k-il即当前递归栈中序中左子树的结点个数
        curRoot.right = dfs(preorder,pl+(k-il)+1,pr,k+1,hashmap);
        return curRoot;
    }
}

Insert picture description here

Guess you like

Origin blog.csdn.net/YouMing_Li/article/details/114238737