LeetCode LCR 124.推理二叉树(哈希表 + 建树)

某二叉树的先序遍历结果记录于整数数组 preorder,它的中序遍历结果记录于整数数组 inorder。请根据 preorder 和 inorder 的提示构造出这棵二叉树并返回其根节点。

注意:preorder 和 inorder 中均不含重复数字。

示例 1:

输入: preorder = [3,9,20,15,7], inorder = [9,3,15,20,7]

输出: [3,9,20,null,null,15,7]

示例 2:

输入: preorder = [-1], inorder = [-1]

输出: [-1]

提示:

  • 1 <= preorder.length <= 3000
  • inorder.length == preorder.length
  • -3000 <= preorder[i], inorder[i] <= 3000
  • inorder 均出现在 preorder
  • preorder 保证 为二叉树的前序遍历序列
  • inorder 保证 为二叉树的中序遍历序列

如何建立一颗二叉树?(数据结构:树 + hash表 / 广搜BFS)-CSDN博客,在我的这篇博客中已经讲解过了如何建树,通过这道题,我们彻底弄明白建树的逻辑

首先呢,复习一下:前序:根左右、中序:左根右、后序:左右根。

无论给出的是那两种遍历我们都可以建出这个树来,以这道题为例子,从前序找根节点,当然我们可以用find函数去找中序当中根节点的位置,在这里呢我们用哈希表来找,因为unordered_map空间是O(1)的,那初始化就是把中序的位置放进哈希表里面

建树么,我们通过不断的递归左子树和右子树,最后可以得出一个完整的树

定义k是中序中根节点的位置,那么我们要找到前序左子树的终点(设为x),则k - mid_l + 1= x - pre_l + 1,解出x,那么中序右子树的起点就是x + 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 {
public:
    unordered_map<int,int> hs;
    TreeNode* dfs(vector<int>& preorder, vector<int>& inorder, int pre_l, int pre_r, int mid_l, int mid_r){
        if(pre_l > pre_r || mid_l > mid_r) return nullptr;
        TreeNode* root = new TreeNode(preorder[pre_l]);
        int k = hs[preorder[pre_l]];
        root -> left = dfs(preorder,inorder,pre_l + 1,pre_l + k - mid_l,mid_l,k - 1);
        root -> right = dfs(preorder,inorder,pre_l + k - mid_l + 1,pre_r,k + 1,mid_r);
        return root;
    } 
    TreeNode* deduceTree(vector<int>& preorder, vector<int>& inorder) {
        int n = preorder.size();
        for(int i=0;i<n;i++) hs[inorder[i]] = i;
        return dfs(preorder,inorder,0,n - 1,0,n - 1);
    }
};

加油

  • 16
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值