【二叉树专题】剑指 Offer 07. 重建二叉树

本问题对应课程链接:剑指offer刷题第三期

要求:
1、请打卡你的解题代码,如果能简单说一下思路则简单说一下思路。
2、给出你代码所用的时间复杂度和空间复杂度

共以下 36 个回答

  • 大大 普通 2023年12月22日 上午11:11
    class Solution {
    public:
    //preorder 先序  根左右
    //inolder 中序   左根右
    
        TreeNode* deduceTree(vector<int>& preorder, vector<int>& inorder) {
         TreeNode* root=new TreeNode();
         if(preorder.size()==0) return NULL;
         root->val=preorder[0];
         int tmp=root->val;
         vector<int>l,r;
         vector<int>lx,rx;
         bool h=true;
         //中序
         for(int i=0;i<inorder.size();i++){
           if(inorder[i]==tmp){
            h=false;
            continue;
           }
           if(h)l.push_back(inorder[i]);
           if(!h)r.push_back(inorder[i]);
         }
         //先序
         int j=1;
         for(;j<=l.size();j++){
           lx.push_back(preorder[j]);
         }
           for(;j<preorder.size();j++){
           rx.push_back(preorder[j]);
         }
    
         root->left=deduceTree(lx,l);
         root->right=deduceTree(rx,r);
         return root;
        }
    };
    
    0 赞同 0 条回复
  • 九号球 普通 2023年11月16日 下午8:44

    “`java
    关键在于分治
    class Solution {
    Map indexByValue = new HashMap<>();
    public TreeNode deduceTree(int[] preorder, int[] inorder) {
    if (preorder == null || inorder == null || preorder.length == 0) {
    return null;
    }
    for (int i = 0; i < inorder.length; i++) { indexByValue.put(inorder[i], i); } return recur(preorder, 0, preorder.length - 1, inorder, 0, inorder.length - 1); }

    public TreeNode recur(int[] preorder, int l1, int r1, int[] inorder, int l2, int r2) {
        if (l1 > r1 && l2 > r2) {
            return null;
        }
        TreeNode root = new TreeNode(preorder[l1]);
        int index = indexByValue.get(preorder[l1]);
        root.left = recur(preorder, l1 + 1, l1 + (index - l2), inorder, l2, index - 1);
        root.right = recur(preorder, l1 + (index - l2) + 1, r1, inorder, index + 1, r2);
        return root;
    }
    

    }

    0 赞同 0 条回复
  • 招舟子 普通 2023年8月26日 下午2:47

    /**
    * Definition for a binary tree node.
    * public class TreeNode {
    * int val;
    * TreeNode left;
    * TreeNode right;
    * TreeNode(int x) { val = x; }
    * }
    */
    class Solution {
    Map<Integer,Integer> map = new HashMap<>();
    public TreeNode buildTree(int[] preorder, int[] inorder) {
    if(preordernull||preorder.length0){
    return null;
    }
    for(int i=0;i<preorder.length;i++){
    map.put(inorder[i],i);
    }
    return recur(preorder,0,preorder.length-1,inorder,0,inorder.length-1);

    }
    TreeNode recur(int[] preorder,int l1,int r1,int[] inorder,int l2,int r2){
        if(l1>r1||l2>r2){
            return null;
        }
        TreeNode node = new TreeNode(preorder[l1]);
        int i = map.get(preorder[l1]);
        node.left = recur(preorder,l1+1,l1+(i-l2),inorder,l2,i-1);
        node.right = recur(preorder,l1+(i-l2)+1,r1,inorder,i+1,r2);
        return node;
    }
    

    }
    根据中序遍历递归求左右子树

    0 赞同 0 条回复
  • jhfuture 普通 2023年8月13日 下午10:05

    “`java
    /**
    * Definition for a binary tree node.
    * public class TreeNode {
    * int val;
    * TreeNode left;
    * TreeNode right;
    * TreeNode(int x) { val = x; }
    * }
    */
    class Solution {
    Map map=new HashMap();
    public TreeNode buildTree(int[] preorder, int[] inorder) {
    if(preorder==null || inorder==null){
    return null;
    }
    for(int i=0;i return f(preorder,0,preorder.length-1,inorder,0,inorder.length-1); }

    TreeNode f(int[] preorder,int l1,int r1,int[] inorder,int l2 ,int r2){
    // 当左右结点为空时停止
    if(l1>r1&&l2>r2){
    return null;
    }
    TreeNode root= new TreeNode(preorder[l1]);
    int i=map.get(preorder[l1]);
    root.left=f(preorder,l1+1,l1+(i-l2),inorder,l2,i-1);
    root.right=f(preorder,l1+(i-l2)+1,r1,inorder,i+1,r2);
    return root;
    }
    }
    一开始觉得很难,后面理解了还好,就是要拆解问题,然后 停止条件那里很巧妙。

    0 赞同 0 条回复
  • CV大神 普通 2023年7月19日 下午11:56
    private HashMap<Integer,Integer> indexMap = new HashMap<>();
    
        /**
         * 思路:
         * 对于任意一颗树而言,前序遍历的形式总是:
         * [ 根节点, [左子树的前序遍历结果], [右子树的前序遍历结果] ]
         * 即根节点总是前序遍历中的第一个节点。而中序遍历的形式总是:
         * [ [左子树的中序遍历结果], 根节点, [右子树的中序遍历结果] ]
         */
        public TreeNode buildTree(int[] preorder, int[] inorder) {
            if(preorder == null || preorder.length == 0){
                return null;
            }
            for (int i = 0; i < inorder.length; i++) {
                indexMap.put(inorder[i],i);
            }
            return buildChildTree(preorder,0,preorder.length-1,inorder,0,inorder.length-1);
        }
    
        public TreeNode buildChildTree(int[] preorder, int preLeft, int preRight,
                                       int[] inorder, int inLeft, int inRight) {
            if (preLeft > preRight) {
                return null;
            }
            int preRoot = preLeft;
            //前序的最左边就是根节点
            int rootValue = preorder[preRoot];
            //根节点在中序中的位置
            int rootIndexInOrder = indexMap.get(rootValue);
            //左树结果的长度 = 中序根位置 - 中序左侧位置
            int leftTreeSize = rootIndexInOrder - inLeft;
            //先构建出子树
            TreeNode childTree = new TreeNode(preorder[preRoot]);
            //构造左边的树
            childTree.left = buildChildTree(preorder, preLeft + 1, preLeft + leftTreeSize,
                    inorder, inLeft, rootIndexInOrder - 1);
            //构造右子树
            childTree.right = buildChildTree(preorder, preLeft + leftTreeSize + 1, preRight,
                    inorder, rootIndexInOrder + 1, inRight);
    
            return childTree;
    
        }
    

    时间复杂度O(n),空间复杂度O(n)

    0 赞同 0 条回复
  • BOZ 普通 2023年7月11日 上午10:59

    【思路】利用前序后序的特性递归实现
    【时间复杂度】由于要遍历inorder数组找到root,复杂度O(nlogn)(如果用map数据结构映射value到idx会变为O(n),但对应的空间消耗会增加)
    【空间复杂度】O(n)

    class Solution {
    public:
        TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
            if (preorder.size() <= 0) return NULL;
    
            function<TreeNode*(int, int, int, int)> _buildTree = [&](int pl, int pr, int il, int ir) -> TreeNode* {
                assert((pr - pl) == (ir - il));
                if (pr - pl <= 0) return NULL;
                TreeNode* root = new TreeNode(preorder[pl]);
    
                // find the root in inorder
                int idx = il;
                while (inorder[idx] != preorder[pl]) idx++;
    
                root->left = _buildTree(pl + 1, pl + 1 + idx - il, il, idx);
                root->right = _buildTree(pl + 1 + idx - il, pr, idx + 1, ir);
    
                return root;
            };
    
            return _buildTree(0, preorder.size(), 0, inorder.size());
        }
    };
    
    0 赞同 0 条回复
  • 断舍离 永久会员 2023年7月11日 上午8:49
    class Solution {
    
        //记录节点值和对应位置索引的映射
        Map<Integer, Integer> map = new HashMap<>();
    
        public TreeNode buildTree(int[] preorder, int[] inorder) {
            if(preorder == null || preorder.length <= 0){
                return null;
            }
            //记录对应节点值和索引的映射
            for(int i = 0; i < inorder.length; i++){
                map.put(inorder[i], i);
            }
            TreeNode root = f(preorder, 0, preorder.length-1, inorder, 0, inorder.length - 1);
            return root;
        }
    
        /*
        * pl:前序遍历数组的起始索引
        * pr:前序遍历数组的结束索引
        * il:中序遍历数组的起始索引
        * ir:中序遍历数组的结束索引
        * */
        public TreeNode f(int[] preorder, int pl, int pr, int[] inorder, int il, int ir){
            //已经为叶子节点
            if(pl > pr && il > ir){
                return null;
            }
            //前序遍历数组的起始索引就是根节点
            TreeNode root = new TreeNode(preorder[pl]);
            //获得根节点下标
            int i = map.get(preorder[pl]);
            //前序遍历左子树:[pl+1, pl + (i - il)]、中序遍历左子树:[il, i-1]
            root.left = f(preorder, pl+1, pl + (i - il), inorder, il, i-1);
            //前序遍历右子树:[pl + (i - il)+1, pr]、中序遍历左子树:[i+1, ir]
            root.right = f(preorder, pl + (i - il)+1, pr, inorder, i+1, ir);
            return root;
        }
    }
    
    0 赞同 0 条回复
  • 憨憨 永久会员 2023年7月10日 下午12:06

    通过递归来将问题分解,再逐个解决

    class Solution {
        HashMap<Integer,Integer> map=new HashMap<>();
        public TreeNode buildTree(int[] preorder, int[] inorder) {
            if(preorder==null||preorder.length<=0){
                return null;
            }
    
            for(int i=0;i<inorder.length;i++){
                map.put(inorder[i],i);
            }
    
            TreeNode root=f(preorder,0,preorder.length-1,inorder,0,inorder.length-1);
    
            return root;
        }
        public TreeNode f(int[] preorder,int l1,int r1,int[] inorder,int l2,int r2){
            if(l1>r1||l2>r2){
                return null;
            }
    
            TreeNode root=new TreeNode(preorder[l1]);
    
            int a=map.get(root.val);
    
            root.left=f(preorder,l1+1,a-l2+l1,inorder,l2,a-1);
            root.right=f(preorder,a-l2+l1+1,r1,inorder,a+1,r2);
    
            return root;
        }
    }
    
    0 赞同 0 条回复
  • 江畅 普通 2023年7月8日 下午9:00
    // 重建二叉树
    // 时间复杂度 O(N)
    // 空间复杂度 O(N)
    class Solution {
    private:
        // 存储中序遍历 <节点值, 遍历中的 index>
        unordered_map<int, int> index;
    
    private:
        /**
         * @brief
         *
         * @param preorder 子前序遍历结果
         * @param inorder 子中序遍历结果
         * @param preorder_left 子前序遍历结果 左节点 在 原前序遍历结果中 的 索引
         * @param preorder_right 子前序遍历结果 右节点 在 原前序遍历结果中 的 索引
         * @param inorder_left 子中序遍历结果 左节点 在 原前序遍历结果中 的 索引
         * @param inorder_right 子中序遍历结果 右节点 在 原前序遍历结果中 的 索引
         * @return TreeNode* 重建的子树
         */
        TreeNode* myBuildTree(
            const vector<int>& preorder, const vector<int>& inorder,
            int preorder_left, int preorder_right,
            int inorder_left, int inorder_right) {
    
            if (preorder_left > preorder_right || inorder_left > inorder_right) {
                return nullptr;
            }
    
            int preorder_root = preorder_left; // 前序遍历序列第一个节点即为子树根节点
    
            // preorder[preorder_root] 即为根节点的值
            int inorder_root = index[preorder[preorder_root]]; // 子树根节点在中序遍历序列中的索引
    
            TreeNode* root = new TreeNode(preorder[preorder_root]);
            int       size_left_subtree = inorder_root - inorder_left;
    
            // preorder: [ 根节点                          , [左子树的前序遍历结果]             ,
            // [右子树的前序遍历结果] ]
            //           [  ...                           , [preorder_left...preorder_right] ,  [...] ]
            // inorder:  [ [左子树的中序遍历结果]           , 根节点                           ,
            // [右子树的中序遍历结果] ]
            //           [ [inorder_left...inorder_right] , inorder_root                    ,   [...] ]
            //
            root->left = myBuildTree(
                preorder, inorder, preorder_left + 1, preorder_left + size_left_subtree, inorder_left,
                inorder_left - 1);
            root->right = myBuildTree(
                preorder, inorder, preorder_left + size_left_subtree + 1, preorder_right,
                inorder_root + 1, inorder_right);
    
            return root;
        }
    
    public:
        // preorder: [ 根节点, [左子树的前序遍历结果], [右子树的前序遍历结果] ]
        // inorder: [ [左子树的中序遍历结果], 根节点, [右子树的中序遍历结果] ]
        TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
            int n = inorder.size();
            for (int i = 0; i < n; ++i) {
                index[inorder[i]] = i;
            }
            return myBuildTree(preorder, inorder, 0, n - 1, 0, n - 1);
        }
    };
    
    0 赞同 0 条回复
  • Sexypig. 普通 2023年7月7日 下午1:28

    构建二叉树的思路如下:

    1. 首先,根据前序遍历的结果,可以确定根节点的值。创建一个根节点,并将其值设为前序遍历结果的第一个元素。
    2. 在中序遍历的结果中,找到根节点的位置。根据中序遍历的性质,根节点的左侧为左子树的中序遍历结果,右侧为右子树的中序遍历结果。

    3. 根据中序遍历的结果,可以确定左子树和右子树的节点数量。在前序遍历的结果中,根节点后面的节点是左子树的前序遍历结果,再之后的节点是右子树的前序遍历结果。

    4. 递归地构建左子树和右子树,重复步骤1到步骤3,直到遍历完所有的节点。

    5. 返回根节点。

    以上是构建二叉树的基本思路,通过递归的方式可以实现该算法。在实际编码中,可以利用哈希表来存储中序遍历结果中每个节点值对应的索引,以提高查找的效率。

    #include<iostream>
    #include<vector>
    #include<unordered_map>
    
    using namespace std;
    
    // 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:
        TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
            if(preorder.size() == 0) return nullptr;
            return buildTreeHelper(preorder,inorder,0,preorder.size()-1,0, inorder.size()-1);
        }
    
        TreeNode* buildTreeHelper(vector<int>& preorder, vector<int>& inorder, 
        int prestart, int preend,  int instart, int inend) {
            if(prestart>preend || instart>inend) return nullptr;
            TreeNode* root = new TreeNode(preorder[prestart]);
            int rootindex = instart;
            while(rootindex<inend&&inorder[rootindex]!=preorder[prestart]) {
                ++rootindex;
            }
            int leftSize=rootindex-instart;
            int rightSize=inend-rootindex;
            root->left=buildTreeHelper(preorder,inorder,prestart+1,prestart+leftSize,instart,rootindex-1); //左子树
            root->right=buildTreeHelper(preorder,inorder,prestart+1+leftSize,preend,rootindex+1,inend); //右子树
            return root;
        }
    };
    
    class Solution2 {
    public:
        TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
            if(preorder.size() == 0) return nullptr;
            for(int i=0;i<inorder.size();++i){
                ump[inorder[i]]=i;
            }
            return buildTreeHelper(preorder,inorder,0,preorder.size()-1,0, inorder.size()-1);
        }
        unordered_map<int,int> ump;
        TreeNode* buildTreeHelper(vector<int>& preorder, vector<int>& inorder, int prestart, int preend, int instart, int inend) {
            if(prestart>preend || instart>inend) return nullptr;
            TreeNode* root = new TreeNode(preorder[prestart]);
            int rootindex = ump[root->val];
            int leftSize=rootindex-instart;
            int rightSize=inend-rootindex;
            root->left=buildTreeHelper(preorder,inorder,prestart+1,prestart+leftSize,instart,rootindex-1); //左子树
            root->right=buildTreeHelper(preorder,inorder,prestart+1+leftSize,preend,rootindex+1,inend); //右子树
            return root;
        }
    };
    
    void printTree(TreeNode* root) {
        if (root == nullptr) {
            return;
        }
        cout << root->val << " ";
        printTree(root->left);
        printTree(root->right);
    }
    
    int main() {
        // 示例输入
        vector<int> preorder = {3, 9, 20, 15, 7};
        vector<int> inorder = {9, 3, 15, 20, 7};
        Solution s;
        // 构建二叉树
        TreeNode* root = s.buildTree(preorder, inorder);
    
        // 打印二叉树(前序遍历)
        printTree(root);
    
        return 0;
    }
    

    0 赞同 0 条回复
  • mpweixin用户 普通 2023年7月5日 下午12:33
    java
    class Solution {
        public TreeNode buildTree(int[] preorder, int[] inorder) {
            //需要用到递归
            //只有一个节点的情况,也是递归的终止条件
            if(preorder.length == 1 && inorder.length == 1 && preorder[0] == inorder[0]) {
                TreeNode root = new TreeNode(preorder[0]);
                root.left = null;
                root.right = null;
                return root;
            }
    
            if(preorder.length == 0 && inorder.length == 0) {
                return null;
            }
    
            int cnt = 0; //记录根节点所在位置
            for(int i = 0; i < inorder.length; i ++) {
                if(inorder[i] == preorder[0]) {//寻找根节点
                    cnt = i;
                }
            }
    
            TreeNode root = new TreeNode(preorder[0]);
            int[] left_inorder = new int[cnt];     //将中序根节点左边分为一组
            int[] left_preorder = new int[cnt]; 
            int[] right_inorder = new int[inorder.length - 1 - cnt]; //将中序根节点右边分为一组
            int[] right_preorder = new int[inorder.length - 1 - cnt];
            for(int i = 0; i < cnt; i ++) { 
                left_inorder[i] = inorder[i];//将inorder根节点左边的移入left_inorder
                left_preorder[i] = preorder[i+1];
            }
    
            for(int i = 0; i < inorder.length - 1 - cnt; i ++) {
                right_inorder[i] = inorder[cnt + 1 + i];
                right_preorder[i] = preorder[cnt + 1 + i];
            }
    
            root.left = buildTree(left_preorder, left_inorder);
            root.right = buildTree(right_preorder, right_inorder);
            return root;
        }
    }
    

    重新开辟了多个数组导致空间复杂度O(N2), 传递数组下标位置再递归就不用另外开辟数组了

    0 赞同 0 条回复
  • ~ 普通 2023年7月4日 下午10:59

    class Solution {
    unordered_map<int, int> valtoindex;
    public:
    TreeNode* buildTree(vector& preorder, vector& inorder) {
    for(int i=0; i<inorder.size(); i++){
    valtoindex[inorder[i]] = i;
    }
    TreeNode* root = build(preorder,0,preorder.size()-1,inorder,0,inorder.size()-1);
    return root;

    }
    TreeNode* build(vector<int>& preorder,int prestart,int preend,vector<int>& inorder,int instart,int inend){
        if (prestart > preend) {
            return nullptr;
        }
        int rootval = preorder[prestart];
        int index = valtoindex[rootval];
        int leftsize = index-instart;
        TreeNode* root = new TreeNode(rootval);
        root->left = build(preorder,prestart+1,leftsize+prestart,inorder,instart,index-1);
        root->right = build(preorder,leftsize+prestart+1,preend,inorder,index+1,inend);
        return root;
    }
    

    };
    时间复杂度O(n),空间复杂度O(n)

    0 赞同 0 条回复
  • 残月冷骄阳 普通 2023年7月4日 下午5:36

    复杂度

    • 时间复杂度:$O(n)$

    • 空间复杂度:$O(n)$

    Code

    /**
     * Definition for a binary tree node.
     * public class TreeNode {
     *     int val;
     *     TreeNode left;
     *     TreeNode right;
     *     TreeNode(int x) { val = x; }
     * }
     */
    class Solution {
        private Map<Integer,Integer> indexMap;
        public TreeNode buildTree(int[] preorder, int[] inorder) {
            indexMap = new HashMap<Integer,Integer>();
            for(int i=0;i < inorder.length;i++){
    
                indexMap.put(inorder[i],i);
            }
            return buildTree(preorder,inorder,0,preorder.length-1,0,inorder.length-1);
    
        }
        public TreeNode buildTree(int[] preorder, int[] inorder,int preorderLeft,int preorderRight ,int inorderLeft,int inorderRight){
            if(preorderLeft>preorderRight){
                return null;
            }
            //确认根节点的下标
            int preorder_root = preorderLeft;
            //根据前序遍历确定根节点值,进而根绝根节点的值找到中序遍历的下标。
            int inorder_root = indexMap.get(preorder[preorder_root]);
            TreeNode rootNode = new TreeNode(preorder[preorder_root]);
            int sizeLeftSubtree = inorder_root - inorderLeft;
            rootNode.left = buildTree(preorder,inorder,preorderLeft+1,preorderLeft+sizeLeftSubtree,inorderLeft,inorder_root-1);
            rootNode.right = buildTree(preorder,inorder,preorderLeft+sizeLeftSubtree+1,preorderRight,inorder_root+1,inorderRight);
            return rootNode;
        }
    }
    
    0 赞同 0 条回复
  • 局外人 普通 2023年7月4日 下午4:32

    思路:根据前序遍历和中序遍历的特性,找到其根节点位置,以及左右子树的范围,通过递归方法,逐步建立各个子树节点,完成对二叉树的重建
    时间复杂度:O(n) 空间复杂度:O(n)

    class Solution {
        public TreeNode build(int[] preorder, int pre_low, int pre_high, int[] inorder, int in_low, int in_high){
            if(pre_low>pre_high)    return null;    //low>high,说明为空树,返回空null
    
            int index_root = 0;
            for(; index_root<=in_high; index_root++){
                if(inorder[index_root]==preorder[pre_low])  break;      //寻找根节点在中序遍历中的位置
            }
    
            int left_size = index_root - in_low;                    //计算左子树节点个数
    
            TreeNode root = new TreeNode(preorder[pre_low]);        //建立根节点
            TreeNode left = build(preorder, pre_low+1, pre_low+left_size, inorder, in_low, index_root-1);   //建立左子树
            TreeNode right = build(preorder, pre_low+left_size+1, pre_high, inorder, index_root+1, in_high);//建立右子树
    
            root.left = left;   
            root.right = right; //左右子树分别拼接
    
            return root;        //返回拼接好后的根节点
        }
        public TreeNode buildTree(int[] preorder, int[] inorder) {
            return build(preorder, 0, preorder.length-1, inorder, 0, inorder.length-1);
        }
    }
    
    0 赞同 0 条回复
  • 名字什么的好麻烦 普通 2023年7月4日 下午2:30

    递归模拟

    class Solution {
        Map<Integer,Integer> map = new HashMap<>();
        int[] pre;
        public TreeNode buildTree(int[] preorder, int[] inorder) {
            pre = preorder;
            for(int i=0;i<inorder.length;i++)
                map.put(inorder[i],i);
            return build(0,preorder.length-1,0,inorder.length-1);
        }
        public TreeNode build(int pl,int pr,int il,int ir){
            if(pl>pr||il>ir)
                return null;
            int pos = pre[pl];
            int index = map.get(pos);
            TreeNode node = new TreeNode(pos);
            node.left = build(pl+1,pl+index-il,il,index-1);
            node.right = build(pl+index-il+1,pr,index+1,ir);
            return node;
        }
    }
    
    0 赞同 0 条回复
  • mpweixin用户 普通 2023年7月4日 上午11:09
    struct TreeNode* buildTree(int* preorder, int preorderSize, int* inorder, int inorderSize) {
        // 若前序遍历或中序遍历为空,则返回空指针
        if (preorderSize == 0 || inorderSize == 0) {
            return NULL;
        }    
        // 创建根节点,并为根节点赋值
        struct TreeNode* root = (struct TreeNode*)malloc(sizeof(struct TreeNode));
        root->val = preorder[0];
        root->left = NULL;
        root->right = NULL;    
        // 在中序遍历中找到根节点的位置
        int rootIndex;
        for (int i = 0; i < inorderSize; i++) {
            if (inorder[i] == preorder[0]) {
                rootIndex = i;
                break;
            }
        }   
        // 递归构建左子树
        root->left = buildTree(preorder + 1, rootIndex, inorder, rootIndex);
    
        // 递归构建右子树
        root->right = buildTree(preorder + rootIndex + 1, preorderSize - rootIndex - 1, inorder + rootIndex + 1, inorderSize - rootIndex - 1);
    
        return root;
    }
    // 打印二叉树的前序遍历结果
    void preorderTraversal(struct TreeNode* root) {
        if (root != NULL) {
            printf("%d ", root->val);
            preorderTraversal(root->left);
            preorderTraversal(root->right);
        }
    }
    

    时间复杂度为O(n)
    空间复杂度为O(n)

    0 赞同 0 条回复
  • 彦,,# 普通 2023年7月4日 上午10:57
    public:
        TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
            this->preorder = preorder;
            for(int i = 0; i < inorder.size(); i++)
                dic[inorder[i]] = i;
            return recur(0, 0, inorder.size() - 1);
        }
    private:
        vector<int> preorder;
        unordered_map<int, int> dic;
        TreeNode* recur(int root, int left, int right) { 
            if(left > right) return nullptr;                        // 递归终止
            TreeNode* node = new TreeNode(preorder[root]);          // 建立根节点
            int i = dic[preorder[root]];                            // 划分根节点、左子树、右子树
            node->left = recur(root + 1, left, i - 1);              // 开启左子树递归
            // 右子树在前序中的根节点位于:根节点+左子树长度+1 = pre_root+in_root-in_left+1
            node->right = recur(root + i - left + 1, i + 1, right); // 开启右子树递归
            return node;                                            // 回溯返回根节点
        }
    
    0 赞同 0 条回复
  • 屠龙手段 普通 2023年7月2日 下午7:39

    分治

    # Definition for a binary tree node.
    # class TreeNode:
    #     def __init__(self, x):
    #         self.val = x
    #         self.left = None
    #         self.right = None
    
    class Solution:
        dic = {}
        def buildTree(self, preorder: List[int], inorder: List[int]) -> TreeNode:
            if not preorder or len(preorder) == 0:
                return None
            for i in range(len(inorder)):
                self.dic[inorder[i]] = i
            return self.subTree(preorder, 0, len(preorder) - 1, inorder, 0, len(inorder) - 1)
    
        def subTree(self, preorder, l1, r1, inorder, l2, r2):
            if l1 > r1 and l2 > r2:
                return None
            root = TreeNode(preorder[l1])
            i = self.dic[preorder[l1]]
            root.left = self.subTree(preorder, l1 + 1, l1 + (i - l2), inorder, l2, i - 1)
            root.right = self.subTree(preorder, l1 + (i - l2) + 1, r1, inorder, i + 1, r2)
            return root
    
    0 赞同 0 条回复
  • 张君雅小妹妹 普通 2023年7月2日 下午2:32

    看完讲解之后会写了,重点在于要把问题分解为子问题
    时间复杂度:O(N)
    空间复杂度:O(N) –这个不太清楚怎么得到的

    class Solution {
        Map<Integer, Integer> map = new HashMap<>();
    
        public TreeNode buildTree(int[] preorder, int[] inorder) {
            if(preorder == null || preorder.length == 0){
                return null;
            }
    
            for(int i = 0; i < inorder.length; i++){
                map.put(inorder[i], i);
            }
    
            TreeNode root = f(preorder, 0, preorder.length - 1, inorder, 0, inorder.length - 1);        
            return root;
        }
    
        public TreeNode f(int[] preorder, int l1, int r1, int[] inorder, int l2, int r2){
            if(l1 > r1 && l2 > r2) return null;
            TreeNode root = new TreeNode(preorder[l1]);
            int i = map.get(preorder[l1]);  // 获得根节点在中序遍历中的位置
            root.left = f(preorder, l1 + 1, l1 + i - l2, inorder, l2, i - 1);
            root.right = f(preorder, l1 + i - l2 + 1, r1, inorder, i + 1, r2);
            return root;
        }
    }
    
    0 赞同 0 条回复
  • 花老爷 普通 2023年7月1日 下午10:40

    没想出来,用官方代码
    时间:O(n)
    空间:O(n)

    class Solution {
        private Map<Integer, Integer> indexMap;
    
        public TreeNode myBuildTree(int[] preorder, int[] inorder, int preorder_left, int preorder_right, int inorder_left, int inorder_right) {
            if (preorder_left > preorder_right) {
                return null;
            }
    
            // 前序遍历中的第一个节点就是根节点
            int preorder_root = preorder_left;
            // 在中序遍历中定位根节点
            int inorder_root = indexMap.get(preorder[preorder_root]);
    
            // 先把根节点建立出来
            TreeNode root = new TreeNode(preorder[preorder_root]);
            // 得到左子树中的节点数目
            int size_left_subtree = inorder_root - inorder_left;
            // 递归地构造左子树,并连接到根节点
            // 先序遍历中「从 左边界+1 开始的 size_left_subtree」个元素就对应了中序遍历中「从 左边界 开始到 根节点定位-1」的元素
            root.left = myBuildTree(preorder, inorder, preorder_left + 1, preorder_left + size_left_subtree, inorder_left, inorder_root - 1);
            // 递归地构造右子树,并连接到根节点
            // 先序遍历中「从 左边界+1+左子树节点数目 开始到 右边界」的元素就对应了中序遍历中「从 根节点定位+1 到 右边界」的元素
            root.right = myBuildTree(preorder, inorder, preorder_left + size_left_subtree + 1, preorder_right, inorder_root + 1, inorder_right);
            return root;
        }
    
        public TreeNode buildTree(int[] preorder, int[] inorder) {
            int n = preorder.length;
            // 构造哈希映射,帮助我们快速定位根节点
            indexMap = new HashMap<Integer, Integer>();
            for (int i = 0; i < n; i++) {
                indexMap.put(inorder[i], i);
            }
            return myBuildTree(preorder, inorder, 0, n - 1, 0, n - 1);
        }
    }
    
    0 赞同 0 条回复
  • 小吕 普通 2023年7月1日 上午10:27

    c++实现
    private:
    TreeNode* traversal(vector& inorder,int inorderBegin,int inorderEnd,vector& preorder,int preorderBegin,int preorderEnd)
    {
    if(preorderBeginpreorderEnd) return NULL;
    int rootValue = preorder[preorderBegin];
    TreeNode* root =new TreeNode(rootValue);
    if(preorderEnd-preorderBegin
    1)return root;

        int delimiterIndex;
        for(delimiterIndex = inorderBegin;delimiterIndex < inorderEnd;delimiterIndex++)
        {
            if(inorder[delimiterIndex]==rootValue)break;
        }
        int leftInorderBegin = inorderBegin;
        int leftInorderEnd = delimiterIndex;
        int rightInorderBegin = delimiterIndex+1;
        int rightInorderEnd = inorderEnd;
    
        int leftPreorderBegin = preorderBegin+1;
        int leftPreorderend = delimiterIndex - inorderBegin + preorderBegin+1;
        int rightPreorderBegin = preorderBegin+1 + delimiterIndex-inorderBegin;
        int rightPreOrderEnd = preorderEnd;
    
        root->left = traversal(inorder,leftInorderBegin,leftInorderEnd,preorder,leftPreorderBegin,leftPreorderend);
        root->right = traversal(inorder,rightInorderBegin,rightInorderEnd,preorder,rightPreorderBegin,rightPreOrderEnd);
        return root;
    }
    

    public:
    TreeNode* buildTree(vector& preorder, vector& inorder) {
    if(preorder.size()0||inorder.size()0)return NULL;
    return traversal(inorder,0,inorder.size(),preorder,0,preorder.size());
    }

    0 赞同 0 条回复
  • 行动派小彩笔 普通 2023年6月30日 下午7:43
     // 通过中序遍历划分左右子树,通过前序遍历来找到根节点
     // 时间复杂度O(n), 空间复杂度O(n),
     // map占有空间n,最坏情况为链表,递归深度O(n),遍历所有节点O(n)
    class Solution {
    public:
        unordered_map<int,int> m;
        TreeNode* rebuildTree(vector<int>& preorder,int l1,int r1,vector<int>& inorder,int l2,int r2)
        {
            if(l1>r1||l2>r2) return NULL;
            TreeNode* root = new TreeNode(preorder[l1]);
            int i = m[preorder[l1]];
            root->left = rebuildTree(preorder,l1+1,l1+(i-l2),inorder,l2,i-1);
            root->right = rebuildTree(preorder,l1+(i-l2)+1,r1,inorder,i+1,r2);
            return root;
        }
        TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
            for(int i =0;i<inorder.size();++i)
            {
                m[inorder[i]] = i;
            }
            TreeNode* root = rebuildTree(preorder,0,preorder.size()-1,inorder,0,inorder.size()-1);
            return root;
        }
    };
    
    0 赞同 0 条回复
  • Jerry 普通 2023年6月29日 下午9:43
    // 递归
    public class Solution {
        int[] preorder;
        Map<Integer, Integer> dict = new HashMap<>();
        public TreeNode buildTree(int[] preorder, int[] inorder) {
            this.preorder = preorder;
            for (int i = 0; i < inorder.length; i++) {
                dict.put(inorder[i], i);
            }
            return recur(0, 0, inorder.length - 1);
        }
    
        TreeNode recur (int root, int left, int right) {
            if (left > right) return null;
            TreeNode node = new TreeNode(preorder[root]);   //中序序列的第一个为 左子树
            int index = dict.get(preorder[root]);
            node.left = recur(root + 1, left, index - 1);   //构建左子树
            node.right = recur(root + index - left + 1, index + 1, right); //构造右子树
            return node;
        }
    
    }
    

    时间复杂度:O(n)
    空间复杂度:O(n)

    0 赞同 0 条回复
  • Yodl. 普通 2023年6月29日 下午9:37
    class Solution {
    public:
        TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
            return build(preorder, inorder, 0, 0, inorder.size() - 1);
        }
        TreeNode* build(vector<int>& preorder, vector<int>& inorder, int root, int start, int end){// 中序的start和end
            if(start > end) return NULL;
            TreeNode *tree = new TreeNode(preorder[root]);
            int i = start;
            while(i < end && preorder[root] != inorder[i]) i++;
            tree->left = build(preorder, inorder, root + 1, start, i - 1);
            tree->right = build(preorder, inorder, root + 1 + i - start, i + 1, end);
            return tree;
        }
    };
    时间复杂度O(n) 空间复杂度O(n)
    
    0 赞同 0 条回复
  • Vow the vow。 普通 2023年6月29日 下午2:19

    根据先序遍历确定根节点,根据中序遍历确定左右子树。

    HashMap<Integer,Integer> map = new HashMap<>();
        public TreeNode buildTree(int[] preorder, int[] inorder) {
            if(preorder == null || preorder.length == 0) return null;
            for(int i = 0; i < inorder.length; i++){
                map.put(inorder[i],i);
            }
            return buildTree(preorder,inorder, 0, 0, inorder.length-1);
        }
    
        public TreeNode buildTree(int[] preorder, int[] inorder,int pl, int il, int ir){
            if(il > ir) return null;
            TreeNode root = new TreeNode(preorder[pl]);
            int index = map.get(preorder[pl]);
            root.left = buildTree(preorder, inorder, pl+1,  il, index-1);
            root.right = buildTree(preorder, inorder, pl+(index-il)+1,  index+1, ir);
            return root;
        }
    
    0 赞同 0 条回复
  • 哈哈哈哈开开心心 普通 2023年6月29日 下午12:16
    # Definition for a binary tree node.
    # class TreeNode:
    #     def __init__(self, val=0, left=None, right=None):
    #         self.val = val
    #         self.left = left
    #         self.right = right
    class Solution:
        def buildTree(self, preorder: List[int], inorder: List[int]) -> Optional[TreeNode]:
    
            inOrderMap = {inorder[i]: i for i in range(len(inorder))}
    
            def buildTreeHelper(l1, r1, l2, r2):
                if l1 > r1:
                    return None
    
                root = TreeNode(preorder[l1])
                inOrderPos = inOrderMap[preorder[l1]]
                # 注意index
                root.left = buildTreeHelper(l1 + 1, l1 + inOrderPos - l2, l2, inOrderPos - 1)
                root.right = buildTreeHelper(l1 + inOrderPos - l2 + 1, r1, inOrderPos + 1, r2)
                return root
    
            return buildTreeHelper(0, len(preorder) - 1, 0, len(inorder) - 1)
    
    0 赞同 0 条回复
  • 怀瑾 永久会员 2023年6月29日 上午11:01

    C++实现

    #include <iostream>
    #include <unordered_map>
    using namespace std;
    
    // 二叉树节点的定义
    struct TreeNode {
        int val;
        TreeNode* left;
        TreeNode* right;
    
        TreeNode(int x) : val(x), left(NULL), right(NULL) {}
    };
    
    TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
        // 使用一个哈希表保存中序遍历结果中每个元素的索引,方便快速查找
        unordered_map<int, int> inorder_map;
        for (int i = 0; i < inorder.size(); ++i) {
            inorder_map[inorder[i]] = i;
        }
    
        // 递归构建二叉树
        return buildTreeHelper(preorder, inorder, 0, preorder.size() - 1, 0, inorder.size() - 1, inorder_map);
    }
    
    TreeNode* buildTreeHelper(vector<int>& preorder, vector<int>& inorder, int preorder_left, int preorder_right, int inorder_left, int inorder_right, unordered_map<int, int>& inorder_map) {
        // 如果前序遍历和中序遍历的左边界大于右边界,表示已经没有节点可以构建了
        if (preorder_left > preorder_right) {
            return nullptr;
        }
    
        // 前序遍历的第一个元素是根节点
        int root_val = preorder[preorder_left];
        TreeNode* root = new TreeNode(root_val);
    
        // 在中序遍历中找到根节点的索引
        int root_index = inorder_map[root_val];
    
        // 左子树的节点个数
        int left_size = root_index - inorder_left;
    
        // 递归构建左子树和右子树
        root->left = buildTreeHelper(preorder, inorder, preorder_left + 1, preorder_left + left_size, inorder_left, root_index - 1, inorder_map);
        root->right = buildTreeHelper(preorder, inorder, preorder_left + left_size + 1, preorder_right, root_index + 1, inorder_right, inorder_map);
    
        return root;
    }
    
    int main() {
        // 输入前序遍历和中序遍历的结果
        vector<int> preorder = {3, 9, 20, 15, 7};
        vector<int> inorder = {9, 3, 15, 20, 7};
    
        // 构建二叉树
        TreeNode* root = buildTree(preorder, inorder);
    
        // 输出根节点的值
        cout << root->val << endl;
    
        return 0;
    }
    
    0 赞同 0 条回复
  • 橙子陈 普通 2023年6月28日 下午11:33
    class Solution {
        Map<Integer, Integer> map = new HashMap();
        public TreeNode buildTree(int[] preorder, int[] inorder) {
            if (null == preorder || preorder.length <= 0){
                return null;
            }
    
            // 将中序元素与对应的下标放入map中
            for (int i = 0; i < inorder.length; i++){
                map.put(inorder[i], i);
            }
    
            return f(preorder, 0, preorder.length-1, inorder, 0, inorder.length-1);
        }
    
        TreeNode f(int[] preorder, int l1, int r1, int[] inorder, int l2, int r2) {
            if (l1 > r1 && l2 > r2) {
                return null;
            }
    
            // 前序遍历的第一个节点为根节点
            TreeNode root = new TreeNode(preorder[l1]);
    
            // 找到前序遍历的根节点在中序遍历中的下标i
            int i = map.get(preorder[l1]);
    
            // 确定前序与中序下标范围,递归左子树与右子树
            root.left = f(preorder, l1+1, l1+i-l2, inorder, l2, i-1);
            root.right = f(preorder, l1+i-l2+1, r1, inorder, i+1, r2);
    
            return root;
        }
    }
    
    0 赞同 0 条回复
  • mpweixin用户 永久会员 2023年6月28日 下午11:14
    //时间O(n) 空间O(n)
    class Solution {
    
        HashMap<Integer,Integer> map = new HashMap();
    
        public TreeNode buildTree(int[] preorder, int[] inorder) {
            if(preorder.length == 0){
                return null;
            }
    
            for(int i = 0;i < inorder.length;i++){
                map.put(inorder[i],i);
            }
    
            return buildTree(preorder,0,preorder.length - 1,inorder,0,inorder.length - 1);
        }
    
        public TreeNode buildTree(int[] preorder, int preLeft,int preRight,int[] inorder,int inLeft,int inRight){
    
            TreeNode root = null;
            if(preLeft <= preRight){
                root =  new TreeNode(preorder[preLeft]);   
                int mid = map.get(preorder[preLeft]); //在中序中的索引
                int lenLeft = mid - inLeft; //  左子树长度
                root.left = buildTree(preorder,preLeft + 1,preLeft + lenLeft,inorder,inLeft,mid - 1);
                root.right = buildTree(preorder,preLeft + lenLeft + 1,preRight,inorder,mid + 1,inRight);
            }
            return root;
        }   
    }
    
    0 赞同 0 条回复
  • 伏月三十 普通 2023年6月28日 下午8:42

    时间复杂度O(n) 空间复杂度O(n)

    class Solution {
        //用来存放中序遍历的<元素,位置>
        Map<Integer,Integer> map=new HashMap<>();
        public TreeNode buildTree(int[] preorder, int[] inorder) {
            if(preorder==null || preorder.length<=0){
                return null;
            }
    
            //把中序遍历的赋值一遍
            for(int i=0;i<inorder.length;i++){
                map.put(inorder[i],i);
            }
    
            TreeNode node=f(preorder,0,preorder.length-1,inorder,0,inorder.length-1);
            return node;
    
        }
        private TreeNode f(int[] preorder,int l1,int r1,int[] inorder,int l2,int r2){
            if(l1>r1 || l2>r2){
                return null;
            }
    
            //头节点
            TreeNode head=new TreeNode(preorder[l1]);
            //头节点在中序遍历中的位置
            int i=map.get(preorder[l1]);
    
            head.left=f(preorder,l1+1,l1+(i-l2),inorder,l2,i-1);
            head.right=f(preorder,l1+(i-l2)+1,r1,inorder,i+1,r2);
    
            return head;
        }
    }
    
    0 赞同 0 条回复
  • 张开怀 普通 2023年6月28日 下午8:31

    前序遍历:中左右
    中序遍历:左中右
    根据前序遍历可以确定节点元素,以前序数组的第一个元素为切割点,先切中序数组,根据中序数组,反过来再切前序数组。一层一层切下去,每次前序数组的第一个元素就是节点元素。

    class Solution{
    public:
           TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder){
                  unordered_map<int, int> map;
                  for(int i=0;i<inorder.size(); i++){
                         map[inorder[i]] = i;
                  }
                  function<TreeNode*(int,int,int,int)> f=[&](int l1, int r1, int l2, int r2) -> TreeNode*{
                         if(l1>r1 || l2>r2){
                                return nullptr;
                         }
                         TreeNode* root = new TreeNode(preorder[l1]);
                         int i= map[preorder[l1]];
                         root->left = f(l1+1, l1+i-l2, l2, i-1);
                         root->right = f(l1+i-l2+1, r1, i+1, r2);
                         return root;
                  };
                  return f(0,preorder.size()-1, 0, inorder.size()-1);
           }
    };
    

    时间复杂度:O(n)
    空间复杂度:O(n)

    0 赞同 0 条回复
  • désire. 普通 2023年6月28日 下午8:01

    C++实现:
    class Solution {
    public:
    TreeNode* build(vector& preorder,int preBegin,int preEnd,vector& inorder,int inBegin,int inEnd)
    {
    if(preBegin preEnd) return NULL;

        int m_val = preorder[preBegin];
        TreeNode* root = new TreeNode(m_val);
    
        if(preEnd - preBegin == 1) return root;
    
        int seg;
        for(seg = inBegin;seg < inEnd;seg++)
        {
            if(inorder[seg] == root->val)
            {
                break;
            }           
        }
        //切割中序,左闭右开
        int InleftBegin = inBegin;//中序左数组
        int InleftEnd = seg; 
    
        int InrightBegin = seg + 1;
        int InrightEnd = inEnd;
    
        int leftlen = InleftEnd - InleftBegin;//左区间长度
        //int righttlen = InrightEnd - InrightBegin;//右区间长度
    
        //切割前序,左闭右开
        int PreleftBegin = preBegin + 1;
        int PreleftEnd = preBegin + 1 + leftlen;
    
        int PrerightBegin = PreleftEnd;
        int PrerightEnd = preEnd;
    
        root->left = build(preorder,PreleftBegin,PreleftEnd,inorder,InleftBegin,InleftEnd);
        root->right = build(preorder,PrerightBegin,PrerightEnd,inorder,InrightBegin,InrightEnd);
        return root;
    }
    TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) 
    {
        if(preorder.size() == 0) return NULL;
        return build(preorder,0,preorder.size(),inorder,0,inorder.size());
    }
    

    };

    0 赞同 0 条回复
  • Ming 普通 2023年6月28日 下午7:55

    复杂度O(n) O(n)

    /**
     * Definition for a binary tree node.
     * public class TreeNode {
     *     int val;
     *     TreeNode left;
     *     TreeNode right;
     *     TreeNode(int x) { val = x; }
     * }
     */
    class Solution {
        Map< Integer, Integer > map = new HashMap();
        public TreeNode buildTree(int[] preorder, int[] inorder) {
            // 前序遍历是根节点,得到根节点通过前序遍历找到左右子树
            // 前序:3 9 20 15 7 
            // 中序:9 3 15 20 7 
            // 第一轮:l1=1 r1=5  l2=1 r2=5 i是3的下标1
            // 第一轮范围: 中:左边[l2, i-1]   右边[i+1,r2]
            //             前:左边[l1, l1+(i-l2)]  右边[l1+(i-l2)+1,r1]
            // 得到i的值十分重要,就是根节点的下标
    
            if(preorder == null || preorder.length <= 0){
                return null;
            }
            // 先将中序元素和下标存入map中
            for(int i = 0; i < inorder.length; i++) {
                map.put(inorder[i],i);
            }
             TreeNode root = f(preorder, 0, preorder.length - 1, inorder, 0, inorder.length - 1);
            return root;
        }
        TreeNode f(int[] preorder, int l1, int r1, int[] inorder, int l2, int r2) {
            // 前序遍历或者中序遍历为空时,表示这棵树不存在,直接返回 null
            if( l1 > r1 || l2 > r2){
                return null;
            }
            //根节点
            TreeNode root = new TreeNode(preorder[l1]);
            //根节点在中序遍历中的下标
            int i = map.get(preorder[l1]);
            //递归求解
            root.left = f(preorder,l1+1, l1+(i-l2), inorder, l2, i-1);
            root.right = f(preorder,l1+(i-l2)+1, r1, inorder, i+1, r2);
            return root;
        }
    }
    
    0 赞同 0 条回复
  • yxy 普通 2023年6月28日 下午7:34

    复杂度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:
        TreeNode* build(vector<int>& preorder, vector<int>& inorder, int ll, int lr, int rl, int rr)
        {
            cout<<ll<<" "<<lr<<" "<<rl<<" "<<rr<<endl; 
            if(ll>lr) return nullptr;
            int val = preorder[ll];
            TreeNode* node = new TreeNode(val);
            int pos = rl;
            while(pos<=rr)
            {
                if(inorder[pos]==val)
                    break;
                pos++;
            }
            node->left = build(preorder, inorder, ll+1,ll+pos-rl,rl,pos-1);// pos-rl=x-ll
            node->right = build(preorder, inorder, ll+pos-rl+1,lr,pos+1,rr);
            return node;
        }
        TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
            if(inorder.size()==0) return nullptr;
            return build(preorder, inorder, 0, preorder.size()-1, 0, preorder.size()-1);
        }
    };
    
    0 赞同 0 条回复
  • 大鑫啊 普通 2023年6月28日 下午7:34

    时空复杂度:O(n)
    1、分析在根据前中序遍历建树的过程中,根据左右子树进行遍历,用到递归
    2、确定递归函数的方法体参数,因为要在数组中进行,所以要设置,位置参数

    class Solution {
        Map<Integer,Integer> map = new HashMap();
        public TreeNode buildTree(int[] preorder, int[] inorder) {
            if(preorder == null || preorder.length <= 0){
                return null;
            }
            // 建立中序遍历数组的映射(就是为了快速求出某个元素的下标)
            for(int i=0;i<inorder.length;i++){
                map.put(inorder[i],i);
            }
            TreeNode root = f(preorder,0,preorder.length-1,inorder,0,inorder.length-1);
            return root;
        }
        TreeNode f(int[] preorder,int l1,int r1,int[] inorder,int l2,int r2){
            // 前序遍历或者中序遍历为空时,表示这棵树不存在,直接返回 null
            if(l1 > r1 || l2 > r2){
                return null;
            }
            TreeNode root = new TreeNode(preorder[l1]);
            int i = map.get(preorder[l1]);
    
            root.left = f(preorder,l1+1,l1+(i-l2),inorder,l2,i-1);
            root.right = f(preorder,l1+(i-l2)+1,r1,inorder,i+1,r2);
            return root;
        }
    }
    
    0 赞同 0 条回复
  • Dsjh 普通 2023年6月28日 下午4:52

    MY

    用中序序列分左右子树

    class Solution {
    public:
        unordered_map m;
        TreeNode* buildTree(vector& preorder, vector& inorder) {
            if(preorder.size()==0){
                return nullptr;
            }
            for(int i=0;i& preorder,vector& inorder,int pre_left,int pre_right,int in_left,int in_right){
            if(pre_left > pre_right){
                return nullptr;
            }
            // pre 的第一个为根
            TreeNode* temp = new TreeNode(preorder[pre_left]);
            // 在 inorder 中找根的下标
            int index = m[preorder[pre_left]];
            // 左子树的数目
            int size_left = index-in_left;
    
            temp->left = myfunc(preorder,inorder,pre_left+1,pre_left+size_left,in_left,index-1);
            temp->right = myfunc(preorder,inorder,pre_left+size_left+1,pre_right,index+1,in_right);
            return temp;
        }
    };
    
    0 赞同 0 条回复

# 回答此问题

后才能回答