剑指offer 07.重建二叉树

这篇博客介绍了如何通过二叉树的前序和中序遍历结果来重建二叉树。核心思路是利用前序遍历的第一个元素作为根节点,并找到它在中序遍历中的位置,从而划分左右子树。通过递归的方式,分别构建左子树和右子树。提供的代码示例展示了两种不同的实现方式,一种基于Python类,另一种基于C++,都实现了此功能。
摘要由CSDN通过智能技术生成

题目:

输入某二叉树的前序遍历和中序遍历的结果,请重建该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。

示例:

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

结果

3
/
9 20
/
15 7

题解:

二叉树前序遍历的顺序为:

先遍历根节点;随后递归地遍历左子树;最后递归地遍历右子树。

二叉树中序遍历的顺序为:

先递归地遍历左子树;随后遍历根节点;最后递归地遍历右子树。

根据前序遍历和中序遍历我们知道。前序数组的一位是根节点,而此时我们再看中序遍历,可以的知,根节点的前面部分就是根节点的左子树,有半部分值其根节点的右子树,当我们求出根节点在中序遍历数组中的位置时,
既可以确定左子树有多少,右子树有多少,因此我们就可以对其中序数组和前序数组进行切割,将大的问题变为小的问题。一下就是本题的详细代码。
在这里插入图片描述在这里插入图片描述

class Solution(object):
    def buildTree(self, preorder, inorder):
    
            
        if len(inorder) == 0:
            
            return None
        
        root = TreeNode(preorder[0])
        
        mid = inorder.index(root.val)
        
        root.left = self.buildTree(preorder[1 : mid + 1], inorder[:mid])
        
        root.right = self.buildTree(preorder[mid+ 1:], inorder[mid + 1:])
         
        return root

/**
 * 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 {
private:

    unordered_map<int, int> index;
public:
    TreeNode* bulidTreeSet(const vector<int>& preorder, const vector<int>& inorder, int pre_left, int pre_right,int ind_left, int ind_right)
    {
        if(pre_left > pre_right)
        {
            return NULL;
        }
        int pre_root = pre_left;

        int ind_root = index[preorder[pre_root]];

        TreeNode* root = new TreeNode(preorder[pre_root]);

        int size_left_sub = ind_root - ind_left;

        root->left = bulidTreeSet(preorder,inorder,pre_left + 1, pre_left+ size_left_sub,ind_left,ind_root - 1);

        root->right = bulidTreeSet(preorder,inorder,pre_left + size_left_sub + 1,pre_right, ind_root + 1, ind_right);

        return root;
    }

    TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
        
        int n = preorder.size();

        for(int i = 0; i<n;i++)
        {
            //构造下标,便于查找元素的下标
            index[inorder[i]] = i;
        }

        return bulidTreeSet(preorder, inorder, 0, n - 1,0, n -1);

    }
};

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值