LeetCode 题解 | 105. 从前序与中序遍历序列构造二叉树(递归 C++)

题目描述(中等难度)

原题链接
在这里插入图片描述

算法

(递归) O ( n ) O(n)

  • 先序遍历第一个元素 a a 即为树的根节点的数值,然后在中序遍历中找到 a a 的位置,通过 a a 把中序遍历分成两个子序列,左边的子序列中的元素构成左子树,右边子序列的元素构成右子树。再对左、右子树进行同样的处理,直到所处理的序列只剩一个元素为止

说明: l 1 > r 1 l_1 > r_1 表示处理序列长度为0,树为空,返回空指针NULL;而 l 2 l_2 r 2 r_2 不需要判断是因为它们的大小关系一定跟 l 1 l_1 r 1 r_1 的大小关系相同的

时间复杂度是 O ( n ) O(n) :可由递归主定理分析法证明 传送门,空间复杂度是 O ( n ) O(n)

C++代码

/**
 * 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:
    // 前序遍历 preorder = [“3”,9,20,15,7]
    // 中序遍历 inorder =  [9,“3”,15,20,7]
    // 根节点"3",把inorder数组分成了两部分
    unordered_map <int, int> hash; // 预处理inorder值和下标的对应关系

    TreeNode* createTree(vector<int>& preorder, vector<int>& inorder, int l1, int r1, int l2, int r2) {
        if (l1 > r1) return NULL; // 树为空,返回空指针
        TreeNode* p = new TreeNode(preorder[l1]);
        int idx = hash[preorder[l1]];

        p->left = createTree(preorder, inorder, l1 + 1, l1 + idx - l2, l2, idx - 1);
        p->right = createTree(preorder, inorder, l1 + idx - l2 + 1, r1, idx + 1, r2);
        return p;
    }

    TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
        int n = inorder.size();
        // 预处理
        for (int i = 0; i < n; i ++) {
            hash[inorder[i]] = i; // 值3 -> 下标1
        }    

        auto root = createTree(preorder, inorder, 0, n - 1, 0, n - 1);

        return root;
    }
};

写在最后:我的博客主要是对计算机领域所学知识的总结、回顾和思考,把每篇博客写得通俗易懂是我的目标,分享技术和知识是一种快乐 ,非常欢迎大家和我一起交流学习,有任何问题都可以在评论区留言,也期待与您的深入交流(^∀^●)

发布了270 篇原创文章 · 获赞 111 · 访问量 11万+

猜你喜欢

转载自blog.csdn.net/qq_43827595/article/details/104440173