一刷剑指Offer_07:重构二叉树

1、题目描述:
在这里插入图片描述
2、思路:

  1. 前序遍历的第 1 个结点一定是二叉树的根结点;
  2. 在中序遍历中,根结点把中序遍历序列分成了两个部分,左边部分构成了二叉树的根结点的左子树,右边部分构成了二叉树的根结点的右子树。
  3. 查找根结点在中序遍历序列中的位置。

在这里插入图片描述

3、代码实现:

class TreeNode {
  int val;
  TreeNode left;
  TreeNode right;
  TreeNode(int x) { val = x; }
}
public class Solution {

    //设置全局变量
    Map<Integer,Integer> map;
    int[] preorder;

    public TreeNode buildTree(int[] preorder, int[] inorder) {
        int preLen = preorder.length;
        int inLen = inorder.length;

        this.preorder = preorder;

        map = new HashMap<>();
        for(int i=0;i<inLen;i++){
            map.put(inorder[i],i);
        }
       return rebuilderTree(0,preLen-1,0,inLen-1);
    }

    private TreeNode rebuilderTree(int preLeft, int preRight, int inLeft, int inRight) {
        if(preLeft>preRight || inLeft>inRight){
            return null;
        }
        //前序遍历的第一个元素一定是根节点
        int pivot = preorder[preLeft];
        TreeNode root = new TreeNode(pivot);

        //根据前序遍历第一个元素的值去中中序遍历中对应的位置
        Integer pivotIndex = map.get(pivot);

        //向左子树递归
        root.left = rebuilderTree(preLeft+1,pivotIndex-inLeft+preLeft,inLeft,pivotIndex-1);
        //向右子树递归
        root.right = rebuilderTree(pivotIndex-inLeft+preLeft+1,preRight,pivotIndex+1,inRight);
        return root;
    }
}
public class Main {
    public static void main(String[] args) {
        int[] preorder = {1,2,4,5,8,9,3,6,10,7};
        int[] inorder = {4,2,8,5,9,1,6,10,3,7};

        Solution binaryTree = new Solution();
        TreeNode treeNode = binaryTree.buildTree(preorder, inorder);
    }
}

4、剑指Offer作答:

class Solution {
    
    //设置全局变量
    Map<Integer,Integer> map;
    int[] preorder;

    public TreeNode buildTree(int[] preorder, int[] inorder) {
        int preLen = preorder.length;
        int inLen = inorder.length;

        this.preorder = preorder;
        
        map = new HashMap<>();
        for(int i=0;i<inLen;i++){
            map.put(inorder[i],i);
        }
        return rebuilderTree(0,preLen-1,0,inLen-1);
    }

    private TreeNode rebuilderTree(int preLeft, int preRight, int inLeft, int inRight) {
        if(preLeft>preRight || inLeft>inRight){
            return null;
        }
        //前序遍历的第一个元素一定是根节点
        int pivot = preorder[preLeft];
        TreeNode root = new TreeNode(pivot);

        //根据前序遍历第一个元素的值去找中序遍历中对应的位置
        Integer pivotIndex = map.get(pivot);

        //向左子树递归
        root.left = rebuilderTree(preLeft+1,pivotIndex-inLeft+preLeft,inLeft,pivotIndex-1);
        //向右子树递归
        root.right = rebuilderTree(pivotIndex-inLeft+preLeft+1,preRight,pivotIndex+1,inRight);
        return root;
    }
}
发布了716 篇原创文章 · 获赞 130 · 访问量 13万+

猜你喜欢

转载自blog.csdn.net/qq_42764468/article/details/105345215