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

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

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

例如,给出

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

返回如下的二叉树:

    3
   / \
  9  20
    /  \
   15   7

--------------------------------------------------------------------------------------------------------------

由前序和中序得到一颗二叉树(递归写法)。终于弄懂了。

Leetcode 105. 从前序与中序遍历序列构造二叉树_第1张图片

要从图中看出的最重要的一点是前序序列怎末划分成两部分。其实可以先在中序中找出左边有n个元素,然后前序除了第一个头节点之后的n个元素就是左子树上的前序序列。
另外的就是右子树的前序序列。注意上图中前序中序分块的颜色匹配。
class Solution {
public:
     vectorpre;
     vectorin;
    TreeNode* build(int st1, int end1 , int st2 , int end2)
    {
        if (st1>end1)                     //判断二叉树是否为空一定要放在最前面,否则下面的new TreeNode(pre[st1])就是错误的语句。
            return NULL;
       int find;
        TreeNode* root=new TreeNode(pre[st1]);
        for (int i=st2;i<=end2;i++)
           { 
             if (in[i]==pre[st1])
             {
                 find=i;
                  break;
             }
        }
        int c=find-st2;                                //注意前序序列的分法。
        root->left=build(st1+1,st1+c,st2,find-1);
        root->right=build(st1+c+1,end1,find+1,end2);
        return root;
    }
    TreeNode* buildTree(vector& preorder, vector& inorder) {
           pre=preorder;
           in=inorder;
       return build(0,pre.size()-1,0,in.size()-1);
    }
};
前序遍历:负责提供根节点
中序遍历:负责给出左子树有多少个元素,右子树有多少个元素。

小技巧点: 预先把中序遍历中的值对应的索引值用hash表记录下来,之后就方便当前子树的根节点在中序遍历中的哪个位置。
/**
 * 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:
    
    unordered_map hash;
    
    TreeNode* dfs(vector& preorder, vector& inorder,int ls,int le,int rs,int re){
        if (ls > le) return nullptr;
        auto root = new TreeNode(preorder[ls]);
        int k = hash[root -> val];
        root -> left = dfs(preorder,inorder,ls + 1,ls + k - rs,rs,k - 1); // 左子树有 (k - 1) - rs + 1 = k - rs个元素 
        root -> right = dfs(preorder,inorder,ls + k - rs + 1,le,k + 1,re);
        return root;
    }

    TreeNode* buildTree(vector& preorder, vector& inorder) {
        int n = preorder.size();
        int m = inorder.size();
        for (int i = 0; i < m; ++i) // 预先把中序遍历中的值对应的索引值用hash表记录下来
            hash[inorder[i]] = i;
        return dfs(preorder,inorder,0,n - 1,0,m - 1);
    }
};

 

你可能感兴趣的:(Leetcode,Acwing)