(难)【07】根据前序,中序遍历重建二叉树

题目

输入某二叉树的前序遍历和中序遍历的结果,请重建该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。
input :
前序遍历 preorder = [3,9,20,15,7]
中序遍历 inorder = [9,3,15,20,7]

思路

这道题我不会做,看了题解之后,才发现有迹可循。可以使用递归。
具体思路我会在代码中注释

收获

递归重建二叉树

代码:

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
class Solution {
    HashMap<Integer,Integer>dict=new HashMap<>();//用于储存中序遍历
    int po[];//因为代码思路通过索引取值,所以需要两个全局变量
    public TreeNode buildTree(int[] preorder, int[] inorder) {
        po = preorder;
        //为什么要存储中序数组?
        //因为有一部需要查前序遍历中的根节点在中序遍历中的位置,以此划分左右子树
        for(int i=0;i<po.length;i++) 
            dict.put(inorder[i],i);
        return recur(0,0,inorder.length-1);
    }

    public TreeNode recur(int pre_root,int in_left,int in_right){
        //递归退出条件为左大右
        if(in_left>in_right) return null;
        var ans = new TreeNode(po[pre_root]);
        //由前序遍历得到的根节点,查到该节点在中序遍历内的索引,即可借此在中序遍历中划分出左右子树。
        int in_root = dict.get(po[pre_root]);

        //在in_left,in_root,in_right中划分
        //左子树
        ans.left = recur(pre_root+1,in_left,in_root-1);

        //右子树的根节点为 原根节点 + 左子树长度 + 1
        ans.right=recur(in_root-in_left+pre_root+1,in_root+1,in_right);
        return ans;
    }
}

猜你喜欢

转载自www.cnblogs.com/Jun10ng/p/12345257.html