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

133 篇文章 0 订阅

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

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

例如,给出

前序遍历 preorder = [3,9,20,15,7]
中序遍历 inorder = [9,3,15,20,7]

返回如下的二叉树:

    3
   / \
  9  20
    /  \
   15   7

解题思路:

需要掌握的基础知识:前序遍历,中序遍历,递归,双指针,哈希。

根据先序遍历的特点,数组的首个元素data必然是根结点,中序遍历的特点是根结点后于左子树访问,于是如果我们能找到data在inorder中出现的位置pos(哈希),那么就能得到pos之前的所有元素(个数num1)为左子树所有元素的中序遍历,pos之后的所有元素(个数num2)则是右子树的中序遍历。根据先序遍历的特点,首个元素必然是根结点,之后的num1个是左子树的先序遍历,再之后的num2个数则是右子树的先序遍历。经过这一波分析,可以看出,大的问题拆解成了两个小问题,而这些小问题不会重复计算,很显然只序递归就能解决。再递归的过程中,这些小的数组没有必要开辟额外的空间,利用双指针,确定在大的数组中的访问范围即可,这样一来就基本完美了。

                   

C++代码
class Solution {
public:
    TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
        int size_pre = preorder.size(), size_in = inorder.size();
        if (size_pre == 0 || size_in == 0) return NULL;
        pre = preorder; in = inorder;
        for (int i = 1; i <= size_in; i++) {
            mp[inorder[i - 1]] = i - 1;
        }
        TreeNode* root = build(0, size_pre, 0, size_in);
        return root;
    }
    TreeNode* build(int pre_first, int pre_last, int in_first, int in_last) {
        if (pre_last == pre_first || in_first == in_last) return NULL;
        if (pre_last - pre_first == 1) return new TreeNode(pre[pre_first]);
        int pos = mp[pre[pre_first]];
        TreeNode* root = new TreeNode(pre[pre_first]);
        root->left = build(pre_first + 1, pre_first + 1 + pos - in_first, in_first, pos);
        root->right = build(pre_first + 1 + pos - in_first, pre_last, pos + 1, in_last);
        return root;
    }
private:
    vector<int> pre, in;
    unordered_map<int, int> mp;
};

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值