重建二叉树

题目来源https://www.acwing.com/problem/content/23/

思路:这是很经典的题,根据前序遍历创建根节点,再通过递归创建左右子树,最后根节点指向左右子树。

具体做法是通过在中序遍历中找到根节点的位置k,分别得到中序遍历左右子树的区间,得到左右区间的长度l,r。

而前序遍历的左子树位置是从根节点接着的l个节点,右子树区间是左子树的下一个节点到最后的节点。

中序遍历遍历找位置用个map即可。由于每个节点只创建一次,时间复杂度o(n)。

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    map<int,int>m;
    vector<int>preorder,inorder;
    TreeNode* buildTree(vector<int>& _preorder, vector<int>& _inorder) {
        preorder=_preorder,inorder=_inorder;
        for(int i=0;i<_inorder.size();i++){
            m[_inorder[i]]=i;
        }        
        return dfs(0,_preorder.size()-1,0,_inorder.size()-1);
    }
    TreeNode* dfs(int pl,int pr,int il,int ir){
        if(pl>pr)return NULL;
        TreeNode* root=new TreeNode(preorder[pl]);
        int k=m[root->val];
        auto left=dfs(pl+1,pl+1+k-il-1,il,k-1);
        auto right=dfs(pl+k-il+1,pr,k+1,ir);
        root->left=left;root->right=right;
        return root;
    }
};

 

posted @ 2020-09-27 13:55  mohari  阅读(83)  评论(0编辑  收藏  举报