剑指 Offer 07. 重建二叉树----c++/python

在这里插入图片描述

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

先遍历根节点;

随后递归地遍历左子树;

最后递归地遍历右子树。

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

先递归地遍历左子树;

随后遍历根节点;

最后递归地遍历右子树。

在「递归」地遍历某个子树的过程中,我们也是将这颗子树看成一颗全新的树,按照上述的顺序进行遍历。挖掘「前序遍历」和「中序遍历」的性质,我们就可以得出本题的做法。

案例讲解:
https://leetcode-cn.com/problems/zhong-jian-er-cha-shu-lcof/submissions/

算法思路:
我们用一个栈和一个指针辅助进行二叉树的构造。初始时栈中存放了根节点(前序遍历的第一个节点),指针指向中序遍历的第一个节点;

我们依次枚举前序遍历中除了第一个节点以外的每个节点。如果 index 恰好指向栈顶节点,那么我们不断地弹出栈顶节点并向右移动 index,并将当前节点作为最后一个弹出的节点的右儿子;如果 index 和栈顶节点不同,我们将当前节点作为栈顶节点的左儿子;

无论是哪一种情况,我们最后都将当前的节点入栈。

/**
 * 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:
    TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
        if(!preorder.size()){
            return nullptr;
        }
        stack<TreeNode*>stk;
        TreeNode* root = new TreeNode(preorder[0]);//前序遍历的第一个元素就是二叉树的根
        stk.push(root);//把根节点放入栈中
        int inorderIndex=0;//指针指向中序遍历的第一个节点,inorderIndex是第一个节点
        for(int i=1;i<preorder.size();i++)//枚举前序遍历中除了第一个节点以外的每个节点
        {
            int preorderVal=preorder[i];
            TreeNode*node=stk.top();
            if(node->val != inorder[inorderIndex]){//如果 index 和栈顶节点不同
                node->left=new TreeNode(preorderVal);//将当前节点作为栈顶节点的左儿子
                stk.push(node->left);
            }else
            //如果 index 恰好指向栈顶节点(无左子树),那么我们不断地弹出栈顶节点并向右移动 index,并将当前节点作为最后一个弹出的节点的右儿子;
            {
                while(!stk.empty()&&stk.top()->val==inorder[inorderIndex])
                {
                    node=stk.top();
                    stk.pop();//弹出栈顶节点
                    ++inorderIndex;//向右移动 index
                }
                node->right=new TreeNode(preorderVal);//将当前节点作为最后一个弹出的节点的右儿子
                stk.push(node->right);
            }
        }
        return root;

    }
};



在这里插入图片描述
在这里插入图片描述

c++:

/**
 * Definition for binary tree
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    TreeNode* reConstructBinaryTree(vector<int> pre,vector<int> vin) {
        if(pre.size() == 0){
            return nullptr;
        }
        int root_val = pre[0];
        int root_index_vin;
        TreeNode* root = new TreeNode(pre[0]);
        for(int i = 0; i < vin.size(); i++){
            if(vin[i] == root_val){
                root_index_vin = i;
                break;
            }
        }
        vector<int>p_l(pre.begin()+1, pre.begin()+root_index_vin+1);//2,4,7
        vector<int>v_l(vin.begin(), vin.begin()+root_index_vin);//4,7,2
        vector<int>p_r(pre.begin()+root_index_vin+1, pre.end());//3,5,6,8
        vector<int>v_r(vin.begin()+root_index_vin+1, vin.end());//5,3,8,6
        
        root->left = reConstructBinaryTree(p_l, v_l);
        root->right = reConstructBinaryTree(p_r, v_r);
        return root;
    
    }
};

python:

class Solution:
    # 返回构造的TreeNode根节点
    def reConstructBinaryTree(self, pre, tin):
        # write code here
        if not pre:
            return None
        # 根节点
        root = TreeNode(pre[0])
        # 根节点在中序遍历中的位置索引
        tmp = tin.index(pre[0])
        # 递归 构造树的左子树
        root.left = self.reConstructBinaryTree(pre[1:tmp+1], tin[:tmp])
        # 递归构造树的右子树
        root.right = self.reConstructBinaryTree(pre[tmp+1:], tin[tmp+1:])
        return root
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值