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

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

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

例如,给出

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

返回如下的二叉树:

    3
   / \
  9  20
    /  \
   15   7

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

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

要从图中看出的最重要的一点是前序序列怎末划分成两部分。其实可以先在中序中找出左边有n个元素,然后前序除了第一个头节点之后的n个元素就是左子树上的前序序列。
另外的就是右子树的前序序列。注意上图中前序中序分块的颜色匹配。
class Solution {
public:
     vector<int>pre;
     vector<int>in;
    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<int>& preorder, vector<int>& 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<int,int> hash;
    
    TreeNode* dfs(vector<int>& preorder, vector<int>& 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<int>& preorder, vector<int>& 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);
    }
};

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值