leetcode 105.从前序与中序遍历序列构造二叉树

题目链接:leetcode 105

1.题目

给定两个整数数组 preorder 和 inorder ,其中 preorder 是二叉树的先序遍历, inorder 是同一棵树的中序遍历,请构造二叉树并返回其根节点。

2.示例

1)示例 1:
输入: preorder = [3,9,20,15,7], inorder = [9,3,15,20,7]
输出: [3,9,20,null,null,15,7]

2)示例 2:
输入: preorder = [-1], inorder = [-1]
输出: [-1]

3.数据范围

1 <= preorder.length <= 3000
inorder.length == preorder.length
-3000 <= preorder[i], inorder[i] <= 3000
preorder 和 inorder 均 无重复 元素
inorder 均出现在 preorder
preorder 保证 为二叉树的前序遍历序列
inorder 保证 为二叉树的中序遍历序列

4.分析

首先明确树的两种遍历,其中先序遍历指的是先遍历根节点,然后遍历左子树,最后遍历右子树,中序遍历指的是先遍历左子树,然后遍历根节点,最后遍历右子树。那么对于一个确定的preorder[x]为根节点的情况下,那么左子树的所有节点必须满足:preorder[y]且preorder[y]在inorder中的位置小于preorder[x]在inorder中的位置,当x+1也满足这个条件时,那么preorder[x+1]即为它的左儿子节点。并且满足上述条件的最大y值为Y,则preorder[Y+1]即为它的右儿子节点(这里需要注意的是,每次根节点需要更新左儿子的范围,也就是必须要小于右儿子开始点)

5.代码

class Solution {
public:
    map<int,int> mp1,mp2,mp3;
    void get_range_left(int pos,int right,vector<int>& preorder){
        int k=mp1[pos];
        while(k+1<=right) {
            if(mp2[preorder[k+1]]<=mp2[pos])
                k++;
            else
                break;
        }mp3[pos]=k;
        if(mp1[pos]+1<=right) get_range_left(preorder[mp1[pos]+1],k,preorder);
        if(k+1<preorder.size()) get_range_left(preorder[k+1],right,preorder);
    }
    void build1(TreeNode* head,int R,vector<int>& preorder, vector<int>& inorder){
        int pos=mp3[head->val],pos1=mp1[head->val];
        if(pos1+1<=min(pos,R)){
            TreeNode *left=new TreeNode(preorder[pos1+1]);head->left=left;
            build1(left,pos,preorder,inorder);
        }
        if(pos+1<=R){
            TreeNode *right=new TreeNode(preorder[pos+1]);head->right=right;
            build1(right,R,preorder,inorder);
        }
    }
    TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
        for(int i=0;i<preorder.size();i++){
            mp1[preorder[i]]=i;
            mp2[inorder[i]]=i;
        }
        get_range_left(preorder[0],preorder.size()-1,preorder);
        // TreeNode *root=new TreeNode(mp3[2]);
       TreeNode *root=new TreeNode(preorder[0]);
       build1(root,preorder.size()-1,preorder,inorder);
       return root;
    }
};

你可能感兴趣的:(leetcode,leetcode,算法)