剑指offer07——重建二叉树

这篇博客介绍了如何通过前序遍历和中序遍历来重建二叉树的算法。前序遍历用于找到根节点,中序遍历则帮助确定左子树和右子树的区间。通过哈希映射存储中序遍历的值和索引,可以有效地找到每个节点的子区间。递归函数`dfs`负责在指定区间内构建子树,直到所有节点都被处理。最终给出了`buildTree`函数实现整个重建过程。
摘要由CSDN通过智能技术生成

前、中序遍历有何意义?

已知条件:前序,中序遍历,重建二叉树。
给出的前序、中序遍历各自有什么意义呢?
前序遍历:根–>左–>右,不难看出无论何时前序遍历第一个肯定是根节点,因此我们找到了根!
剩下只要找到左孩子和右孩子就行了,把左子树、右子树抽象成只有一个节点:左孩子、右孩子,找到这俩孩子就能重构树了,递归就是一个抽象、抽象、抽/(ㄒoㄒ)/~~象的过程!!!

我们看中序遍历:左–>根–>右,咦,只要知道了根节点在哪,左孩子右孩子就在左右两侧,因此我们就可以通过中序遍历找出左右孩子。

因此,前序遍历的意义就是找根节点中序遍历就是找左节点和右节点(区间长度)。但是如果左右孩子是棵树的话,那通过中序遍历划分的就是一个区间。不着急~~~知道了这个区间(长度),我们就能返回前序遍历划分左右子树区间,每颗子树又可以看作一棵独立的树,再按原先步骤重复划分即可,这就开始没完没了地递归了,何时才到头?我们定义递归函数TreeNode* dfs(int L,int R,vector<int>& preorder,unordered_map<int,int>& hmap,int in_L,int in_R,vector<int>& inorder)的意义为在[L,R]这个区间内进行重建树操作,当且仅当L>R时返回空姐点。

小技巧:利用哈希表把中序遍历的所有值和索引作为对存起来(key:值,val: 索引),这样通过前序遍历所得的根节点值就能找到中序遍历中对应根节点的位置(part pos),区间也就划分好,区间长度也就能知道。

在这里插入图片描述

代码

各位大神面前我就不班门弄斧了,直接上代码,跟我一样的小白们看不懂的欢迎评论区留言~~~

class Solution {
public:
    
    TreeNode* dfs(int pre_L,int pre_R,vector<int>& preorder,unordered_map<int,int>& hmap,int in_L,int in_R,vector<int>& inorder)
    {
        if(pre_L-pre_R > 0 || in_L-in_R > 0)
            return NULL;
        
        TreeNode* root = new TreeNode(preorder[pre_L]);
        int partpos = hmap[preorder[pre_L]];
        root->left = dfs(pre_L+1, pre_L + (partpos-in_L),preorder,hmap,in_L,partpos-1,inorder);
        root->right = dfs(pre_L + (partpos-in_L)+1,pre_R,preorder,hmap,partpos+1,in_R,inorder);

        return root;
    }
    
    
    
    
    TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
        //hmap key:中序遍历的值 val:中序遍历的索引
        unordered_map<int,int> hmap;
        for(int i=0;i<inorder.size();i++)
        {
            hmap[inorder[i]] = i;
        }
        
        return  dfs(0,preorder.size()-1,preorder,hmap,0,inorder.size()-1,inorder);

    }
};```

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值