【算法练习Day16】找树左下角的值路径总和 从中序与后序遍历序列构造二叉树

news2024/12/27 13:37:47

在这里插入图片描述

​📝个人主页:@Sherry的成长之路
🏠学习社区:Sherry的成长之路(个人社区)
📖专栏链接:练题
🎯长路漫漫浩浩,万事皆有期待

文章目录

  • 找树左下角的值
  • 路径总和
  • 从中序与后序遍历序列构造二叉树
  • 总结:

找树左下角的值

513. 找树左下角的值 - 力扣(LeetCode)
在这里插入图片描述

寻找树的左下角值,这里的左下角值指的是该树的最后一行中的最靠左节点,一定不要理解错误,两个条件缺一不可,最容易的一个方法是广搜来遍历到树的最后一层然后直接取该层的第一个节点即可,也可以用深搜,不过稍显麻烦。

class Solution {
public:
    int maxDepth=INT_MIN;
    int result;
    void traversal(TreeNode* root,int depth)
    {
        if(root->left==nullptr&&root->right==nullptr)
        {
            if(depth>maxDepth)
            {
                maxDepth=depth;
                result=root->val;
            }
            return;
        }
        if(root->left)
        {
            traversal(root->left,depth+1);
        }
        if(root->right)
        {
            traversal(root->right,depth+1);
        }
        return;
    }
    int findBottomLeftValue(TreeNode* root) {
        traversal(root,0);
        return result;
    }
};

深搜的思路是:使用递归,结束条件是碰到叶子节点即判断一下,该层是否为最深,如果不是最深那么略过去,如果是最深的话取一下当前节点。这里不需要担心我们取的当前节点是否是该层第一个,原因是首先我们定义一个全局变量来指出当前所遍历过的最深有多深,第二点我们一定会先遍历到最左侧。

class Solution {
public:
    int findBottomLeftValue(TreeNode* root) {
        queue<TreeNode*> q;
        int result;
        q.push(root);
        while(!q.empty())
        {
            int size=q.size();
            for(int i=0;i<size;i++)
            {
                TreeNode*cur=q.front();q.pop();
                if(i==0)result=cur->val;//存储的是每一行的第一个元素
                if(cur->left)q.push(cur->left);
                if(cur->right)q.push(cur->right);
            }
        }
        return result;
    }
};

上述代码是广搜的思路,思路具体为将头节点先加入队列中,然后根据广搜的模板代码写出剩余过程,也就是先将队列头部节点取出,把它的左右子树都加入进来,需要在模板代码内加入的新东西是,我们需要做一个判断确保每一次第一个遍历到的最左节点数值能够直接存入在变量中(由于广搜的特性,所以我们遍历的每层第一个元素一定是最左边的)。

路径总和

112. 路径总和 - 力扣(LeetCode)
在这里插入图片描述

这道递归题是找到一个路径直接返回,所以我们需要注意,在单层递归逻辑中要处理当发现一条正确的路径后,如何将true向上层一次返回,尽快跳出循环,这是本题的关键所在。

class Solution {
public:
    bool traversal(TreeNode* cur,int count)
    {
        if(!cur->left&&!cur->right&&count==0)
        {
            return true;
        }
        if(!cur->left&&!cur->right)
        {
            return false;
        }
        if(cur->left)
        {
            count-=cur->left->val;
            if(traversal(cur->left,count))
            return true;
            count+=cur->left->val;
        }
        if(cur->right)
        {
            count-=cur->right->val;
            if(traversal(cur->right,count))
            return true;
            count+=cur->right->val;
        }
        return false;
    }
    bool hasPathSum(TreeNode* root, int targetSum) {
        if(root==nullptr)
        {
            return false;
        }
        return traversal(root,targetSum-root->val);
    }
};

代码整体思路并不算难,用一个全局变量来保存该条路径总值等于多少,遍历到叶子节点我们做一次判断,如果总和等于目标值则向上返回true,这就是下面单层递归代码需要做的判断步骤,if上一层返回的是true,则继续向上返回直到跳出递归,这种思路在寻找一条正确答案就退出的题目来说,十分重要。

值得注意的是,我们在遍历到叶子节点时候,进入了递归的结束判断,不要忘记此时要在sum里加入当前叶子节点的值!这一点同样很重要,很容易就给落下,导致题目怎么做都是错误的,当然如果加入了还是false,那么在else里不要忘记将它减去(相当于回溯)。到全部都遍历完,如果还是不能返回true,那么直接返回false,表示无法找到。

这道题难的是递归的不同情况我们如何处理它们的返回,如果能搞得懂,那么还是可以做出来的。顺便说一句,如果在传入参数的时候传入的是目标值targetsum-头节点,再用传进来的目标值依次减去路径各节点判断到叶子节点时候是否等于0,那么在递归函数的结束判断代码部分会省一点力,当然递归部分代码目标值也要减去它下一个子树对应的val。

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

106. 从中序与后序遍历序列构造二叉树 - 力扣(LeetCode)
在这里插入图片描述

这道题是给一个中序遍历二叉树的数组和后序遍历二叉树的数组,用这两个数组,构造出来它实际想要表示的唯一的二叉树,并返回该二叉树的头部节点。

这道题的具体思路是:后序遍历的每次最后一个节点是每一个子树的中间节点。因为后序遍历左右中的遍历特点,它的最后一个节点首先应该是头部节点,也就是所谓的根节点,我们找到根节点了之后,在中序遍历数组中找到中节点所在的位置,将该数组分成左右两部分,左部分是左子树,右部分则是右子树所组成的节点,在做完这些的时候不要忘记将后序遍历的最后一个节点删除,以免重复进行数组的分割。

然后我们再进行后序数组的分割,我们之前已经说了后序数组是用来确定哪些节点此时应该做中节点的,我们按照中序数组左右部分的大小来切割后序数组,使它们能够左右部分一样大,然后在链接root->left和root->right时调用递归传进中序数组左部分(右部分)和后序数组左部分(右部分)即可。分为左右部分子树后,我们传进来的后续数组的部分就显得相当的重要了,他们的最后一个数据即是中间节点,重复以上步骤,直到节点全部插入,最重要的结束判断语句不要忘记,如果传进来的后序数组没有元素,则说明此时该侧子树节点全部安放完毕,不要漏掉这一步。主要是为了防止新节点存入没有必要的空指针,以及后来的遍历进入死循环,在全部递归完成return root即可。

class Solution {
public:
    TreeNode* traversal(vector<int>&inorder,vector<int>postorder)
    {
        if(postorder.size()==0)
        {
            return nullptr;
        }
        // 后序遍历数组最后一个元素,就是当前的中间节点
        int rootValue=postorder[postorder.size()-1];
        TreeNode* root=new TreeNode(rootValue);

        if(postorder.size()==1)
        {// 叶子节点
            return root;
        }
		// 找到中序遍历的切割点
        int delimiterIndex;
        for(delimiterIndex=0;delimiterIndex<inorder.size();delimiterIndex++)
        {
            if(inorder[delimiterIndex]==rootValue)
            {
                break;
            }
        }
        // 切割中序数组
        // 左闭右开区间:[0, delimiterIndex)
        vector<int> leftInoder(inorder.begin(),inorder.begin()+delimiterIndex);
        // [delimiterIndex + 1, end)
        vector<int> rightInoder(inorder.begin()+delimiterIndex+1,inorder.end());
		// postorder 舍弃末尾元素
        postorder.resize(postorder.size()-1);
		// 切割后序数组
        // 依然左闭右开,注意这里使用了左中序数组大小作为切割点
        // [0, leftInorder.size)
        vector<int> leftPostorder(postorder.begin(),postorder.begin()+leftInoder.size());
        // [leftInorder.size(), end)
        vector<int> rightPostoder(postorder.begin()+leftInoder.size(),postorder.end());

        root->left=traversal(leftInoder,leftPostorder);
        root->right=traversal(rightInoder,rightPostoder);

        return root;
    }
    TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder) {
        if(inorder.size()==0||postorder.size()==0)
        {
            return nullptr;
        }
        return traversal(inorder,postorder);

    }
};

总结:

今天我们完成了找树左下角的值、路径总和、从中序与后序遍历序列构造二叉树三道题,相关的思想需要多复习回顾。接下来,我们继续进行算法练习。希望我的文章和讲解能对大家的学习提供一些帮助。

当然,本文仍有许多不足之处,欢迎各位小伙伴们随时私信交流、批评指正!我们下期见~

在这里插入图片描述

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

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

相关文章

PDF编辑和OCR文字识别工具ABBYY FineReader PDF

ABBYY FineReader PDF是一款专业的OCR文字识别和PDF编辑工具&#xff0c;可以帮助用户更好地处理和管理PDF文档。以下是ABBYY FineReader PDF的一些特点&#xff1a; 1. 文字识别精准&#xff1a;ABBYY FineReader PDF具有强大的OCR文字识别功能&#xff0c;可以将PDF中的文字…

大数据学习(2)Hadoop-分布式资源计算hive(1)

&&大数据学习&& &#x1f525;系列专栏&#xff1a; &#x1f451;哲学语录: 承认自己的无知&#xff0c;乃是开启智慧的大门 &#x1f496;如果觉得博主的文章还不错的话&#xff0c;请点赞&#x1f44d;收藏⭐️留言&#x1f4dd;支持一下博>主哦&#x…

浅谈风力发电场集中监控系统解决方案

作为清洁能源之一&#xff0c;风力发电场近几年装机容量快速增长。8月17日&#xff0c;国家能源局发布1-7月份全国电力工业统计数据。截至7月底&#xff0c;全国累计发电装机容量约27.4亿千瓦&#xff0c;同比增长11.5%。其中&#xff0c;太阳能发电装机容量约4.9亿千瓦&#x…

绝地求生大吃鸡攻略,让你成为顶级战士!

近年来&#xff0c;绝地求生越来越受到玩家们的喜爱&#xff0c;吃鸡成为了很多人的娱乐方式。作为一个资深吃鸡玩家&#xff0c;今天我要和大家分享一些提高战斗力的干货&#xff0c;以及一些方便吃鸡作图与查询的实用工具。 首先&#xff0c;提高战斗力是吃鸡游戏中最重要的一…

青菜学蒸馒头

作为一个会写代码的厨师&#xff0c;做好一笼松软可口的馒头那是必修的基本功&#xff0c;今天我就来试验一把&#xff0c;具体过程如下&#xff1a; 一、材料准备 1、200克面粉 2、2克干酵母粉 3、35度左右温开水一碗 4、白糖少许 二、制作步骤 1、面粉的选择 面粉的种…

html调用手机打电话、发短信网页源码/热门挪车自动拨打电话、发送短信html源码

源码介绍&#xff1a; 这个是自动拨打发送挪车短信电话源码&#xff0c;纯html临时停车挪车网站源码。利用html拨打电话、发送短信链接&#xff0c;js拨打电话。可以html调用手机打电话、发短信功能。使用H5移动HTML特殊链接实现打电话,发短信,发邮件的功能&#xff0c;非常方…

回归算法全解析!一文读懂机器学习中的回归模型

目录 一、引言回归问题的重要性文章目的和结构概览 二、回归基础什么是回归问题例子&#xff1a; 回归与分类的区别例子&#xff1a; 回归问题的应用场景例子&#xff1a; 三、常见回归算法3.1 线性回归数学原理代码实现输出例子&#xff1a; 3.2 多项式回归数学原理代码实现输…

2023年中国汽车后市场行业研究报告

第一章 行业概况 1.1 定义 汽车后市场行业在中国的快速崛起&#xff0c;反映了汽车产业链的完善和消费者需求的多样化。这个行业涵盖了汽车销售后&#xff0c;围绕汽车使用过程中涌现的各类服务和交易活动。它不仅为消费者提供了汽车使用过程中所需的全方位服务&#xff0c;也…

【C/C++笔试练习】常见进制转换、宏的定义和特点、sizeof与strlen、字符串函数、统计回文、连续最大和

文章目录 C/C笔试练习1.常见进制转换&#xff08;1&#xff09;进制前缀&#xff08;2&#xff09;进制转换 2.宏的定义和特点&#xff08;3&#xff09;宏的定义&#xff08;4&#xff09;有关宏的计算 3.sizeof与strlen&#xff08;5&#xff09;sizeof和strlen的差别 4.字符…

2023年中国复合门产量、销量、产业链及市场规模分析[图]

复合门是一种由木材和人造板材等材料组合而成的门&#xff0c;具有较高的强度和稳定性。它采用多层材料交叉堆叠、胶合而成&#xff0c;能够有效防止门扇变形、开裂和变色等问题&#xff0c;同时还具备一定的防火、防潮和防虫功能。 复合门产业链 资料来源&#xff1a;共研产业…

【开题报告】如何借助chatgpt完成毕业论文开题报告

步骤 1&#xff1a;确定论文主题和研究问题 首先&#xff0c;你需要确定你的论文主题和研究问题。这可以是与软件开发、算法、人工智能等相关的任何主题。确保主题具有一定的研究性和可行性。 步骤 2&#xff1a;收集相关文献和资料 在开始撰写开题报告之前&#xff0c;收集相…

软件培训测试高级工程师多测师肖sir__html之作业11

html之作业 案例1&#xff1a; 截图&#xff1a; 代码&#xff1a; <!DOCTYPE html> <html><head><meta charset"UTF-8"><title>表单</title></head><body><table style"background-color:red" bo…

全新第二代SCB后备保护器:保护电器的后备力量

在电气设备中&#xff0c;浪涌保护器&#xff08;SPD&#xff09;是一种重要的防雷装置&#xff0c;它可以在电源线路中并联接入&#xff0c;当发生过电压或雷电冲击时&#xff0c;将其导向地线&#xff0c;从而保护后端设备免受损坏。然而&#xff0c;SPD本身也会因为长期使用…

【算法设计与分析】— —实现最优载的贪心算法

&#x1f383;欢迎大家前去观看我的算法设计与分析专栏&#xff1a; 算法设计与分析_IT闫的博客-CSDN博客 希望对大家有所帮助&#xff01; &#x1f383;个人专栏&#xff1a; &#x1f42c; 算法设计与分析&#xff1a;算法设计与分析_IT闫的博客-CSDN博客 &#x1f433;Java…

Java 客户端调用 WebService 接口的一种方式

文章目录 1. SoapUI 测试 WebService 接口2. Java 访问 WebService 接口 1. SoapUI 测试 WebService 接口 通过SoapUI创建一个SOAP Project&#xff1b; 项目名称自定义&#xff0c;WSDL地址维护WebService接口地址。点击OK即可 项目创建完成后&#xff0c;展开WebService项&…

孙哥分布式VIP课程

杜绝一两门课程割韭菜&#xff0c;杜绝引流之后换老师&#xff0c;全行业唯一支持全套试听的良心课程。 你目前学习提高跳槽是否有如下痛点 1、网上开源课程“琳琅满目”&#xff0c;学完后还是掌握的不够扎实&#xff0c;理解的不够透彻&#xff0c;学无所成2、学了若干知识…

浏览器插件开发爬虫记录

常用爬虫有各种各样的反爬限制&#xff0c;而如果是小数据量并且该网站反爬手段非常厉害的前提下&#xff0c;可以考虑使用浏览器插件作为爬虫手段 基本代码来源于这位博主分享的插件代码&#xff0c; 主要在他的基础上加了 请求代理、管理面板、脚本注入拦截到的请求数据和管…

Windows服务器获取本地文件夹文件

1、直接复制粘贴 通过远程连接到这个服务器&#xff0c;然后本机到服务器能直接粘贴复制文件上去 注&#xff1a;首先服务器要先开启远程桌面哦 2、Windows远程连接 有的不能复制粘贴的&#xff0c;可以用第二种方法。 ①、windowsR,输入mstsc ②、点击“选项”按钮&#x…

linux中Crontab定时参数

注&#xff1a;图片转载于 点我进入图片出处 * * * * * sh /data/var/test.sh >> test_crontab_log.log分钟 0~59 0表示没分周 小时 0~23 0表示每小时 天 1~31 *表示每天 月 1~12 *表示每月 周 0~7 */0/7表示每周

pytorch实现经典神经网络:VGG16模型之初探

文章链接 https://blog.csdn.net/weixin_44791964/article/details/102585038?ops_request_misc%257B%2522request%255Fid%2522%253A%2522169675238616800211588158%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fblog.%2522%257D&request_id16967523861680…