LeetCode二叉树经典题目(六):特殊位置构造二叉树

news2024/11/18 7:25:46

目录

21. LeetCode404. 左叶子之和

22.LeetCode513. 找树左下角的值

23. LeetCode112. 路径总和

24. LeetCode113. 路径总和 II

25. LeetCode106. 从中序与后序遍历序列构造二叉树

26. LeetCode105. 从前序与中序遍历序列构造二叉树​编辑

27. LeetCode654. 最大二叉树


21. LeetCode404. 左叶子之和

思路:
1.左叶子:是叶子节点且是其父节点的左子节点
2.由于我们需要知道父子关系,所以不能深入到叶子节点再做判断,而是在叶子节点的上一层就需要处理了
3.后序遍历

递归:
class Solution {
public:
    int sumOfLeftLeaves(TreeNode* root) {
        //base case
        if(root==NULL)return 0;
        if(root->left==NULL&&root->right==NULL)return 0;

        //向左右子树索要信息
        int leftSum=sumOfLeftLeaves(root->left);
        int rightSum=sumOfLeftLeaves(root->right);
        //处理当前节点
        if(root->left!=NULL&&root->left->left==NULL&&root->left->right==NULL){//中
            leftSum=root->left->val;//左子节点是左叶子
        }
        return leftSum+rightSum;
    }
};

迭代:关键点在于判断左叶子
class Solution {
public:
    int sumOfLeftLeaves(TreeNode* root) {
        stack<TreeNode*>stk;
        int res=0;
        stk.push(root);
        while(!stk.empty()){
            TreeNode*node=stk.top();
            stk.pop();
            if(node->left!=NULL&&node->left->left==NULL&&node->left->right==NULL){
                res+=node->left->val;
            }
            if(node->right)stk.push(node->right);
            if(node->left)stk.push(node->left);
        }
        return res;
    }
};

22.LeetCode513. 找树左下角的值

递归:由于是找左下角值,所以我们应当优先处理左子树
很多人可能会疑惑为什么取值不是最后一层其他节点的呢?
其实最后一层最先被遍历到的节点必定是最左边的节点,因为我们是优先处理左子树的。当遍历到最后一层其他节点时,深度depth等于maxDepth,不满足修改值的条件。
class Solution {
public:
    int maxDepth=INT_MIN;
    int res=0;

    void traversal(TreeNode*node,int depth){
        //结束条件,叶子节点
        if(node->left==NULL&&node->right==NULL){
            if(depth>maxDepth){
                res=node->val;
                maxDepth=depth;
                return;
            }
        }
        if(node->left){
            depth++;
            traversal(node->left,depth);
            depth--;//回溯
        }
        if(node->right){
            depth++;
            traversal(node->right,depth);
            depth--;//回溯
        }
    }

    int findBottomLeftValue(TreeNode* root) {
        traversal(root,1);
        return res;
    }
};

迭代:层序遍历
class Solution {
public:
    int findBottomLeftValue(TreeNode* root) {
        queue<TreeNode*>que;
        int res=0;
        que.push(root);
        while(!que.empty()){
            res=que.front()->val;
            for(int i=que.size();i>0;i--){
                TreeNode*node=que.front();
                que.pop();
                if(node->left)que.push(node->left);
                if(node->right)que.push(node->right);
            }
        }
        return res;
    }
};

23. LeetCode112. 路径总和

递归:
class Solution {
public:
    bool process(TreeNode*node,int sum){
        //base case
        if(node->left==NULL&&node->right==NULL&&sum-node->val==0)return true;
        if(node->left==NULL&&node->right==NULL&&sum-node->val!=0)return false;

        if(node->left){
            if(process(node->left,sum-node->val))return true;
        }
        if(node->right){
            if(process(node->right,sum-node->val))return true;
        }
        return false;
    }

    bool hasPathSum(TreeNode* root, int targetSum) {
        if(root==NULL)return false;
        return process(root,targetSum);
    }
};

迭代:
class Solution {
public:
    bool hasPathSum(TreeNode* root, int targetSum) {
        if(root==NULL)return false;
        //<节点,路径和>
        stack<pair<TreeNode*,int>>stk;
        stk.push(pair<TreeNode*,int>(root,root->val));
        while(!stk.empty()){
            pair<TreeNode*,int>node=stk.top();
            stk.pop();
            if(!node.first->left&&!node.first->right&&node.second==targetSum)return true;
            if(node.first->right){
                stk.push(pair<TreeNode*,int>
                         (node.first->right,node.second+node.first->right->val));
            }
            if(node.first->left){
                stk.push(pair<TreeNode*,int>
                         (node.first->left,node.second+node.first->left->val));
            }
        }
        return false;
    }
};

24. LeetCode113. 路径总和 II

class Solution {
public:
    vector<vector<int>>res;

    //vec必须是赋值拷贝,不能是引用,否则会把所有路径值都加入到同一个集合中
    void traversal(TreeNode*node,vector<int>vec,int sum){
        if(node->left==NULL&&node->right==NULL&&sum-node->val==0){
            vec.push_back(node->val);
            res.push_back(vec);
            return;
        }
        if(node->left==NULL&&node->right==NULL&&sum-node->val!=0){
            return;
        }
        if(node->left){
            vec.push_back(node->val);
            traversal(node->left,vec,sum-node->val);
            vec.pop_back();//回溯
        }
        if(node->right){
            vec.push_back(node->val);
            traversal(node->right,vec,sum-node->val);
            vec.pop_back();//回溯
        }
    }

    vector<vector<int>> pathSum(TreeNode* root, int targetSum) {
        if(root==NULL)return {};
        traversal(root,{},targetSum);
        return res;
    }
};

25. LeetCode106. 从中序与后序遍历序列构造二叉树

思路:
中序:左中右
后序:左右中
1.后续数组为0,空节点
2.后续数组的最后一个元素为节点元素
3.寻找中序数组位置作为切割点
4.切中序数组
5.切后序数组
6.递归处理左区间后区间
class Solution {
public:
    map<int,int>dic;//用于映射中序遍历元素对应的索引

    TreeNode*traversal(vector<int>&inorder,vector<int>&postorder,int l1,int r1,int l2,int r2){
        if(l1>r1&&l2>r2)return NULL;
        TreeNode*root=new TreeNode(postorder[r2]);
        int index=dic[root->val];
        root->left=traversal(inorder,postorder,l1,index-1,l2,l2+index-l1-1);
        root->right=traversal(inorder,postorder,index+1,r1,l2+index-l1,r2-1);
        return root;
    }

    TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder) {
        if(inorder.size()==0)return NULL;
        for(int i=0;i<inorder.size();i++){
            dic[inorder[i]]=i;
        }
        return traversal(inorder,postorder,0,inorder.size()-1,0,postorder.size()-1);
    }
};

26. LeetCode105. 从前序与中序遍历序列构造二叉树

前序和后序无法确定一棵树,因为无法分割左右子树
class Solution {
public:
    map<int,int>dic;//映射中序数组索引

    TreeNode*traversal(vector<int>&preorder,vector<int>&inorder,int l1,int r1,int l2,int r2){
        if(l1>r1&&l2>r2){
            return NULL;
        }
        TreeNode*root=new TreeNode(preorder[l1]);
        int index=dic[root->val];
        root->left=traversal(preorder,inorder,l1+1,l1+1+index-1-l2,l2,index-1);
        root->right=traversal(preorder,inorder,l1+1+index-1-l2+1,r1,index+1,r2);
        return root;
    }

    TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
        if(preorder.size()==0){
            return NULL;
        }
        for(int i=0;i<inorder.size();i++){
            dic[inorder[i]]=i;
        }
        return traversal(preorder,inorder,0,preorder.size()-1,0,inorder.size()-1);
    }
};

27. LeetCode654. 最大二叉树

本题和前两题构造二叉树有异曲同工之处,都是先创建父节点,然后分割数组进行递归
class Solution {
public:
    //找到nums在l和r之间最大值的索引
    int indexOfMax(vector<int>&nums,int l,int r){
        int res=l;
        while(l<=r){
            res=nums[l]>nums[res]?l:res;
            l++;
        }
        return res;
    }

    TreeNode*traversal(vector<int>&nums,int l,int r){
        if(l>r)return NULL;
        int index=indexOfMax(nums,l,r);
        //以最大值为父节点值
        TreeNode*root=new TreeNode(nums[index]);
        root->left=traversal(nums,l,index-1);//前缀数组是左子树
        root->right=traversal(nums,index+1,r);//后缀数组是右子树
        return root;
    }

    TreeNode* constructMaximumBinaryTree(vector<int>& nums) {
        return traversal(nums,0,nums.size()-1);
    }
};

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/149472.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

LED、Mini LED、Micro LED、LCD、OLED技术

1、传统led、miniled、microled的异同 2、OLED OLED&#xff08;Organic Light-Emitting Diode&#xff09;&#xff0c;又称为有机电激光显示、有机发光半导体&#xff08;Organic Electroluminescence Display&#xff0c;OLED&#xff09;。OLED属于一种电流型的有机发光器…

S32K144-hello_word点灯

官方提供了很多的参考例程&#xff0c;每个历程分别配置了不同的外设&#xff0c;这里挨个尝试解读一下。 示例效果 RGB红灯绿灯交替闪烁。 导入示例 示例文件所在目录&#xff1a; 该示例使用PCC和PORT模块交替切换两个LED。 硬件连接 配置引脚功能 生成代码 S32DS自带引…

C#上位机基础学习_登录窗体的创建方法和步骤

C#上位机基础学习_登录窗体的创建方法和步骤 本次和大家分享如何制作一个简单的登录窗体。具体的方法和步骤可以参考以下内容: 如下图所示,打开Visual Studio 2019,新建一个Windows 窗体应用(.NET Framework), 如下图所示,在窗体中添加Label标签、Text文本框、Button按…

Java中常用API总结(5)—— Object类中的深克隆和浅克隆

对象克隆一、前言二、浅克隆1.概述2.实例1️⃣思路2️⃣继承cloneable接口底层原理3️⃣重写clone方法底层原理3.代码实现三、深克隆1.概述2.实例3.代码实现四、结语一、前言 本文将详细讲述Object类中的对象克隆方法&#xff0c;其中包含深克隆和浅克隆&#xff0c;两者有一定…

算法竞赛100天第2天——STL IN C++(算法竞赛必备知识总结汇总)

本文已收录于专栏 &#x1f332;《百日算法竞赛》&#x1f332; 目录 前言&#xff1a; 序列容器 序列的要求&#xff1a; 1.vector vector常用方法 vector遍历 2、deque 头文件 方法 3、list 头文件 方法 4、queue 方法&#xff1a; 关联容器 1、map 2、se…

SWPUCTF 2022新生赛部分wp

&#x1f60b;大家好&#xff0c;我是YAy_17&#xff0c;是一枚爱好网安的小白。 本人水平有限&#xff0c;欢迎各位大佬指点&#xff0c;一起学习&#x1f497;&#xff0c;一起进步⭐️。⭐️此后如竟没有炬火&#xff0c;我便是唯一的光。⭐️[SWPUCTF 2022 新生赛]ez_ez_ph…

【算法】链表

❤️ Author&#xff1a; 老九 ☕️ 个人博客&#xff1a;老九的CSDN博客 &#x1f64f; 个人名言&#xff1a;不可控之事 乐观面对 &#x1f60d; 系列专栏&#xff1a; 文章目录链表数组转链表链表转数组往链表的前面增加一个节点获得指定位置的值在链表的末尾增加一个节点在…

我最近发现的一些问题。

‍‍ 大家好&#xff0c;我是小z&#xff0c;也可以叫我阿粥~这段时间看了不少分析报告&#xff0c;启发颇多。也发现有一些普遍存在且很容易误导分析师的问题。在聊问题之前&#xff0c;先给大家分享一个&#xff08;我刚写的&#xff09;小故事&#xff1a;有一个学生…

Pytorch 多项式拟合

目录 1、训练误差和泛化误差 2、独立同分布假设 3、欠拟合和过拟合 4、多项式回归 1、训练误差和泛化误差 训练误差&#xff08;training error&#xff09;是指&#xff0c; 模型在训练数据集上计算得到的误差。 泛化误差&#xff08;generalization error&#xff09;是指…

【OpenCV 例程 300篇】255.OpenCV 实现图像拼接

『youcans 的 OpenCV 例程300篇 - 总目录』 【youcans 的 OpenCV 例程 300篇】255.OpenCV 实现图像拼接 6.2 OpenCV 实现图像拼接 OpenCV中图像的数据结构是Numpy数组&#xff0c;使用切片方法可以实现图像的裁剪&#xff0c;使用数组堆叠方法可以实现图像的拼接。 Numpy 函数…

K8S Replication Controller 示例

K8S Replication Controller Replication Controller可确保在任何时间运行指定数量的pod副本。换句话说&#xff0c;ReplicationController确保一个pod或一组同类pod始终处于可用状态。 可以理解为Replication Controller &#xff08;RC&#xff09;是基于 K8S Pod对象之上的…

PR采购申请启用灵活工作流配置

目录 1. 检查系统基础工作流配置 2. 激活标准场景模版 WS02000458 3. 维护收件箱操作按钮文本 4. 维护任务代理及激活事件 5. 配置Inbox审批页面 6. PR灵活工作流启动配置 7. 为流程设置代理人 8. 配置工作流场景 9. 可扩展部分 官方Help文档路径&#xff1a; SAP He…

算法_杨氏矩阵_杨氏矩阵算法_剑指offer

目录 一、问题描述 二、问题分析 三、算法设计 ​四、代码实现 一、问题描述 有一个数字矩阵&#xff0c;矩阵的每行从左到右是递增的&#xff0c;矩阵从上到下是递增的&#xff0c;请编写程序在这样的矩阵中查找某个数字是否存在。 要求&#xff1a;时间复杂度小于O(N);…

【目标检测】Cascade RCNN中的两个常见问题

一、关于mismatch问题 在training阶段和inference阶段使用不同的阈值很容易导致mismatch&#xff0c;什么意思呢&#xff1f; 在training阶段&#xff0c;由于给定了GT&#xff0c;所以可以把与GT的IoU大于阈值的proposals作为正样本&#xff0c;这些正样本参与之后的bbox回归…

【C语言】深入浅出讲解函数栈帧(超详解 | 建议收藏)

&#x1f680;write in front&#x1f680; &#x1f4dd;个人主页&#xff1a;认真写博客的夏目浅石. &#x1f381;欢迎各位→点赞&#x1f44d; 收藏⭐️ 留言&#x1f4dd; &#x1f4e3;系列专栏&#xff1a;凡人修C传 &#x1f4ac;总结&#xff1a;希望你看完之后&…

基于机器学习与协同过滤的图书管理推荐系统

基于机器学习与协同过滤的图书推荐系统 一、系统结构图 二、Demo示例 完整源码可联系博主微信【1257309054】 点我跳转 三、K-means聚类机器学习推荐算法 1、原理 从数据库中 1、首先获取书籍类别 2、获取用户注册时勾选喜欢的类别&#xff0c;勾选的为1&#xff0c;否则…

让 Java Agent 在 Dragonwell 上更好用

本文是《容器中的Java》系列文章之 3/n&#xff0c;欢迎关注后续连载 &#x1f603; 。1 背景 随着越来越多的云原生微服务应用的大规模部署&#xff0c;大家对微服务治理的能力需求越来越强。 Java Agent技术能够让业务专注于业务逻辑&#xff0c;与此同时&#xff0c;中间…

kali渗透测试到底该如何学?

1、渗透测试是什么&#xff1f; 渗透测试&#xff0c;是为了证明网络防御按照预期计划正常运行而提供的一种机制。渗透测试是通过各种手段对目标进行一次渗透&#xff08;攻击&#xff09;&#xff0c;通过渗透来测试目标的安全防护能力和安全防护意识。打个比方&#xff1a;比…

手写spring12(把aop动态代理整合到spring生命周期)

文章目录目标设计项目结构四、实现1、定义Advice拦截器链2、定义Advisor访问者3、方法前置拦截器——MethodBeforeAdviceInterceptor4、代理工厂——ProxyFactory5、融入Bean生命周期的自动代理创建者——InstantiationAwareBeanPostProcessor 、DefaultAdvisorAutoProxyCreato…

什么是3dMax中的“块”?如何在3dMax中使用“块”?

3dMax 块简介 3dMax 是一款用于设计 3d 模型的软件,在 3d 建模图形专业人士中最受欢迎。我们可以在此软件中导入不同类型的预设计 3d 模型,以简化我们的工作。块是不同类型的 3d 模型,您可以从互联网上下载,然后将它们导入到 3dMax 软件的项目工作中,以节省您的时间。在本…