保研机试之【构造二叉树】

参考:东哥带你刷二叉树(构造篇) | labuladong 的算法笔记

建议先过一遍:今天是二叉树~-CSDN博客,very重要!

然后再过一遍(理解怎么应用方法):保研机试之[三道二叉树习题,思路为主]-CSDN博客

二叉树的构造问题一般都是使用「分解问题」的思路:构造整棵树 = 根节点 + 构造左子树 + 构造右子树

第一题: 654. 最大二叉树 - 力扣(LeetCode)

动规写法直接秒了~

前序位置先找数组中最大值,创建新节点;后序位置填充新节点的左右指针

/**
 * 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:
    TreeNode* construct(vector<int>& nums,int l,int r,int len){
        if(l>r || l>=len || r<0){
            return nullptr;
        }
        //前
        /*寻找最大值*/
        int find_max=0;
        int idx=l;
        for(int i=l;i<=r;i++){
            if(find_max<nums[i]){
                find_max=nums[i];
                idx=i;
            }
        }
        TreeNode* root=new TreeNode;
        root->val=find_max;

        TreeNode* left=construct(nums,l,idx-1,len);
        //中
        TreeNode* right=construct(nums,idx+1,r,len);
        //后
        root->left=left;
        root->right=right;
        return root;
    }
    TreeNode* constructMaximumBinaryTree(vector<int>& nums) {
        int len=nums.size();
        TreeNode* res=construct(nums,0,len-1,len);
        return res;
    }
};

第二题: 105. 从前序与中序遍历序列构造二叉树 - 力扣(LeetCode)

这道题我原来做过:力扣--从前序与中序遍历序列构造二叉树-CSDN博客 

如今一看,可能当时做的毫无章法,现在再来看这道题

一样的思路:前序位置先找数组中最大值,创建新节点;后序位置填充新节点的左右指针,只不过传递数组索引较为麻烦,我将preorder和inorder的左右索引都进行传递

/**
 * 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:
    TreeNode* build(vector<int>& preorder,vector<int>& inorder,int p_l,int p_r,int i_l,int i_r,int len){
        if(p_l>p_r || i_l>i_r || p_l>=len || p_r<0 || i_l>=len || i_r<0){
            return nullptr;
        }
        int cnt=preorder[p_l];
        TreeNode* node=new TreeNode;
        node->val=cnt;
        int idx=0;
        for(int i=i_l;i<=i_r;i++){
            if(inorder[i]==cnt){
                idx=i;
                break;
            }
        }
        int cnt_l=idx-i_l;
        int cnt_r=i_r-idx;
        //前
        TreeNode* left=build(preorder,inorder,p_l+1,p_l+cnt_l,i_l,i_l+cnt_l-1,len);
        //中
        TreeNode* right=build(preorder,inorder,p_l+cnt_l+1,p_r,i_l+cnt_l+1,i_r,len);
        //后
        node->left=left;
        node->right=right;
        return node;
    }
    TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
        int len=preorder.size();
        TreeNode* root=build(preorder,inorder,0,len-1,0,len-1,len);
        return root;
    }
};

第三题:(有思路就行,只是数组索引传递不同)106. 从中序与后序遍历序列构造二叉树 - 力扣(LeetCode)

 第四题:(有思路就行,只是数组索引传递不同)889. 根据前序和后序遍历构造二叉树 - 力扣(LeetCode)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值