力扣 105. 从前序与中序遍历序列构造二叉树 题解

力扣 105. 从前序与中序遍历序列构造二叉树 题解

根据一棵树的前序遍历与中序遍历构造二叉树。

注意:
你可以假设树中没有重复的元素。

例如,给出
前序遍历 preorder = [3,9,20,15,7]
中序遍历 inorder = [9,3,15,20,7]
返回如下的二叉树:

在这里插入图片描述

二叉树结构

public class TreeNode {
    
    
    int val;
    TreeNode left;
    TreeNode right;
    TreeNode() {
    
    }
    TreeNode(int val) {
    
     this.val = val; }
    TreeNode(int val, TreeNode left, TreeNode right) {
    
    
      this.val = val;
      this.left = left;
      this.right = right;
    }
}

思路

class Solution {
    
    
    public TreeNode buildTree(int[] preorder, int[] inorder) {
    
    
        return bulid(preorder, 0, preorder.length - 1, inorder, 0, inorder.length-1);
    }
    /**
    *preorder为前序遍历数组
    *preStart为前序遍历的起始指针
    *preEnd为前序遍历的结尾指针
    *inorder为中序遍历数组
    *inStart为中序遍历的起始指针
    *inEnd为中序遍历的结尾指针
    **/
    public TreeNode bulid(int[] preorder, int preStart, int preEnd, int[] inorder, int inStart, int inEnd){
    
    
    	//终止条件
        if(preStart > preEnd || inStart > inEnd) return null;
        //前序遍历的preStart为树的根
        TreeNode root = new TreeNode(preorder[preStart]);
        //找到中序遍历中对应值为preorder[preStart]的下标
        for(int i=inStart; i<=inEnd; i++){
    
    
            if(preorder[preStart] == inorder[i]){
    
    
            	/**左子树**/
            	//前序遍历指针+1,结尾为中序遍历i的位置,减去起始的中序遍历位置再加上preStart
            	//中序遍历以i为分界点,左右分开
                root.left = bulid(preorder, preStart+1, i-inStart+preStart, inorder, inStart, i-1);
                /**右子树**/
                root.right = bulid(preorder, i-inStart+preStart+1, preEnd, inorder, i+1, inEnd);
            }
        }
        return root;
    }
}

在这里插入图片描述
优化

因为每一次都需要在中序遍历inorder里面找下标,所以用HashMap存值和下标,方便寻找

class Solution {
    
    
    HashMap<Integer,Integer> map = new HashMap<>();
    public TreeNode buildTree(int[] preorder, int[] inorder) {
    
    
        for(int i=0; i<inorder.length; i++){
    
    
            map.put(inorder[i], i);
        }
        return bulid(preorder, 0, preorder.length - 1, inorder, 0, inorder.length-1);
    }
    /**
    *preorder为前序遍历数组
    *preStart为前序遍历的起始指针
    *preEnd为前序遍历的结尾指针
    *inorder为中序遍历数组
    *inStart为中序遍历的起始指针
    *inEnd为中序遍历的结尾指针
    **/
    public TreeNode bulid(int[] preorder, int preStart, int preEnd, int[] inorder, int inStart, int inEnd){
    
    
    	//终止条件
        if(preStart > preEnd || inStart > inEnd) return null;
        //前序遍历的preStart为树的根
        TreeNode root = new TreeNode(preorder[preStart]);
        //找到中序遍历中对应值为preorder[preStart]的下标
        int i = map.get(preorder[preStart]);
        /**左子树**/
        //前序遍历指针+1,结尾为中序遍历i的位置,减去起始的中序遍历位置再加上preStart
        //中序遍历以i为分界点,左右分开
        root.left = bulid(preorder, preStart+1, i-inStart+preStart, inorder, inStart, i-1);
        /**右子树**/
        root.right = bulid(preorder, i-inStart+preStart+1, preEnd, inorder, i+1, inEnd);

        return root;
    }
}

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_40660894/article/details/113733460
今日推荐