《二叉树还原》

首先我们需要知道的是中序遍历,因为这样我们才能知道根的左右子树,否则无法实现还原一棵唯一的二叉树。

已知先序遍历,中序遍历,还原二叉树。

我们知道先序遍历中第一次遇到的一定是根节点。

然后我们就可以根据先序中的根节点位置,在中序遍历中取开辟左右子树。

即递归取分解左右子树。

按照中序的思想,我们会一直去找到左子树的根节点,所以在先序中一开始的一段一般都是左子树的根节点。

具体的做法,就是在一段中先确定根的位置,然后就能左右去分解,然后找出下一次递归的下标和区间即可。

/**
 * 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:
    void dfs(vector<int>& preorder, vector<int>& inorder,TreeNode* pre,int id,int pos,int L,int r) {
        if(L > r) return ;
        int rt = preorder[pos];
        int i = L;
        TreeNode* node = new TreeNode(rt);
        if(id == 0) pre->left = node;
        else pre->right = node;
        while(inorder[i] != rt) {
            ++i;
        }
        dfs(preorder,inorder,node,0,pos + 1,L,i - 1);
        dfs(preorder,inorder,node,1,pos + (i - L) + 1,i + 1,r);
    }
    TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
        TreeNode * rt = new TreeNode(0);
        int len = preorder.size();
        dfs(preorder,inorder,rt,0,0,0,len - 1);
        return rt->left;
    }
};
View Code

已知后序遍历,中序遍历,还原二叉树。

 我们可以知道后序遍历一棵子树内的最后一个位置一定是根。

所以我们每次分解子树的时候,都提取它的最后一个作为根,然后去递归分解。

把范围都扣准就行。注意的是为了效率每次我们要去找根在中序中的位置,所以用map来提高速度。

这里发现了一个问题,如果把map也作为形参去传递的话就会超时。

猜测应该是因为map里的东西太多了,每次传递都要做一个拷贝,深度大了之后就超时了。

所以开到全局去用。

class Solution {
    int post_idx;
    unordered_map<int, int> mp;
public:
    TreeNode* dfs(vector<int>& inorder, vector<int>& postorder,int le,int ri,int le2,int ri2) {
        if(le > ri || le2 > ri2) return nullptr;
        int pos = mp[postorder[ri2]];
        TreeNode* node = new TreeNode(postorder[ri2]);
        node->left = dfs(inorder,postorder,le,pos - 1,le2,le2 + (pos - le - 1));
        node->right =  dfs(inorder,postorder,pos + 1,ri,le2 + (pos - le),ri2 - 1);
        return node;
    }
    TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder) {
        int idx = 0;
        for (auto& val : inorder) {
            mp[val] = idx++;
        }
        return dfs(inorder,postorder,0, (int)inorder.size() - 1,0, (int)inorder.size() - 1);
    }
};
View Code

 

posted @ 2021-04-22 16:10  levill  阅读(255)  评论(0编辑  收藏  举报