Leetcode 105 106 重构二叉树

本文详细解析了LeetCode上的两道经典题目105和106,即根据遍历序列重构二叉树的问题。通过对先序、中序和后序遍历的理解,提出了有效的算法思路,并附上了C++实现代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Leetcode上105,106题很相似,都是重构二叉树的题

题目:

105:

Given preorder and inorder traversal of a tree, construct the binary tree.

Note:
You may assume that duplicates do not exist in the tree.

For example, given

preorder = [3,9,20,15,7]
inorder = [9,3,15,20,7]

Return the following binary tree:

    3
   / \
  9  20
    /  \
   15   7

给定一个二叉树的前序和中序遍历的结果,要求推测构造出对应二叉树

106:

给定一个二叉树的中序和后序遍历的结果,要求推测构造出对应二叉树

 

 

解题思路

 

首先我们知道各个遍历的顺序,先序遍历:根 左 右

                                                   中序遍历:左 根 右

                                                   后序遍历:左 右 根

 

我们可以根据这些规则作出解题思路

105题

preorder = [3,9,20,15,7] inorder = [9,3,15,20,7]

我们首先通过先序遍历 ,可以知道根为 3

而知道根为3后,通过中序遍历,可以知道 左子树包含 9, 右子树包含 15,20,7

这时候 我们就可以将先序遍历划分为3段 ,根3,左子树{9},右子树{20 15 17}

我们在重复刚才的步骤,可以不断向下推进,从而得到整个树的结构

 

对于 106题,这一次将前序改为了后序遍历,其实原理大致一样,因为后序遍历的顺序是  左 右 根

所以这一次我们要从 尾部开始搜索。

代码:

105:

/**
 * 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:
     int findIndex(vector<int>&inorder, int start, int end, int key){
        int i;
        for(i=start;i<=end;i++){
            if(inorder[i] == key)
                break;
        }
        return i;
    }
    
    TreeNode* buildStep(vector<int>& preorder, vector<int>& inorder,int start, int end ,int p_start){
        if(start>end||p_start<0) return NULL;
        int mid=findIndex(inorder,start,end,preorder[p_start]);
        TreeNode * root= new TreeNode(preorder[p_start]);
        root->left=buildStep(preorder,inorder,start,mid-1,p_start+1);
        root->right=buildStep(preorder,inorder,mid+1,end,p_start+mid-start+1);
            
        return root;
    }
    TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
        return buildStep(preorder,inorder,0,preorder.size()-1,0);
    }
};

106

/**
 * 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:
    int findIndex(vector<int>&inorder, int start, int end, int key){
        int i;
        for(i=start;i<=end;i++){
            if(inorder[i] == key)
                break;
        }
        return i;
    }
    
    TreeNode* buildStep( vector<int>& inorder,vector<int>& postorder,int start, int end ,int p_start){
        if(start>end||p_start<0) return NULL;
        int mid=findIndex(inorder,start,end,postorder[p_start]);
        TreeNode * root= new TreeNode(postorder[p_start]);
        root->right=buildStep(inorder,postorder,mid+1,end,p_start-1);
        root->left=buildStep(inorder,postorder,start,mid-1,p_start-1-end+mid);
            
        return root;
    }
    TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder) {
        return buildStep(inorder,postorder,0,postorder.size()-1,postorder.size()-1);
    }
};

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值