• 47 从前序与中序遍历序列构造二叉树



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

    先序无法确定子树大小,中序找不到根;所以用先序找根,用中序找大小

    题解1 递归

    /**
     * Definition for a binary tree node.
     * struct TreeNode {
     *     int val;
     *     TreeNode *left;
     *     TreeNode *right;
     *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
     *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
     *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
     * };
     */
    class Solution {
        unordered_map<int, int> idx;
    public:
    // 先序自上而下,中序确定左右子树大小
        TreeNode* build(vector<int>& preorder, vector<int>& inorder, int pre_left, int pre_right, int in_left, int in_right){
            if(pre_left > pre_right) return nullptr;
            
            // 用前序找根(把树单元化,叶子结点看作无左右子的根), 中序找左树大小
            int root_idx = pre_left;
            // 哈希表查此根结点在中序遍历数组的位置
            int root_in = idx[preorder[root_idx]];
            
            TreeNode* root = new TreeNode(preorder[root_idx]);
            // 左树大小
            int num_left = root_in - in_left;
    		// left树,越往下走右边界越收紧
    		// 但在preoreder里涉及到赋值,需要往后找,左边界+1
            root->left = build(preorder, inorder, pre_left+1, pre_left+num_left, in_left, root_in-1);
            // right树,越往下走左边界约收紧
            // 同样在preorder里涉及到遍历问题(先序遍历:遍历完左再遍历右,所以到右侧应该是+num_left+1)
            // 再inorder里就是在根节点的右侧,root_in+1即可
            root->right = build(preorder, inorder, pre_left+num_left+1, pre_right, root_in+1, in_right);
            return root;
        }
    
        TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
            int s = preorder.size();
            for(int i = 0; i < s; i++){
                idx[inorder[i]] = i;
            }
            // 含右边界的版本
            return build(preorder, inorder, 0, s-1, 0, s-1);
        }
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45

    在这里插入图片描述

    题解2 迭代

    class Solution {
        unordered_map<int, int> idx;
    public:
        TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
            int s = preorder.size();
            TreeNode* root = new TreeNode(preorder[0]);
            stack<TreeNode*> rstk;
            rstk.push(root);
            int idx = 0;
            for(int i = 1; i < s; i++){
                int val = preorder[i];
                TreeNode* node = rstk.top();
                // 判断当前node是不是叶子结点(拐点)
                if(node->val != inorder[idx]){
                    node->left = new TreeNode(val);
                    rstk.push(node->left);
                }else{
                    // 用中序查当前先序的结点i是不是右树
                    while(rstk.size() && rstk.top()->val == inorder[idx]){
                        node = rstk.top();
                        rstk.pop();
                        idx ++;
                    }
                    node->right = new TreeNode(val);
                    rstk.push(node->right);
                }
            }
            return root;
        }
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30

    在这里插入图片描述

  • 相关阅读:
    Qt-FFmpeg开发-打开本地摄像头(6)
    Windows 11 中打印时提示打印机不兼容,都来是“+”惹的祸
    华为云大数据BI赋能企业数字化发展
    【深入浅出 Yarn 架构与实现】6-2 NodeManager 状态机管理
    vue3 teleport的使用
    图像的数据类型
    书籍《软技能》读后感
    Spring Bean的生命周期
    14:00面试,14:06就出来了,问的问题有点变态。。。
    VSCode配置MingW编译调试环境
  • 原文地址:https://blog.csdn.net/qq_43402798/article/details/133752418