DAY16||513.找树左下角的值 |路径总和|从中序与后序遍历序列构造二叉树

news2024/12/23 3:44:05

513.找树左下角的值

题目:513. 找树左下角的值 - 力扣(LeetCode)

给定一个二叉树的 根节点 root,请找出该二叉树的 最底层 最左边 节点的值。

假设二叉树中至少有一个节点。

示例 1:

输入: root = [2,1,3]
输出: 1

示例 2:

输入: [1,2,3,4,null,5,6,null,null,7]
输出: 7

递归法

前中后序都可以,因为没有中的处理逻辑。

回溯的思想体现在depth,要在递归语句前++,语句后--,其实就是回退的操作,去遍历右子树。

本题理解,找到最后一行的左节点就行,深度最大。


class Solution {
public:
    int maxdepth=INT_MIN;
    int result;
    void trversal(TreeNode*root,int depth)
    {
        if(root->right==NULL&&root->left==NULL)//找到叶子节点,查看是否是最大深度的
        {
            if(depth>maxdepth)
            {
            maxdepth=depth;
            result=root->val;
            }
            return;
        }

        if(root->left)
        {
            depth++;
            trversal(root->left,depth);
            depth--;
        }
        if(root->right)
        {
            depth++;
            trversal(root->right,depth);
            depth--;
        }
    return;
    }
    int findBottomLeftValue(TreeNode* root) {
        trversal(root,0);

        return result;

    }
};

迭代法

使用层序遍历比较简单。。

class Solution {
public:
    
    int findBottomLeftValue(TreeNode* root) {
    queue<TreeNode*>que;
    int result=0;
    if(root)que.push(root);
    
    while(!que.empty())
    {
        int size=que.size();

        for(int i=0;i<size;i++)
        {
            TreeNode*node=que.front();
            que.pop();//其实没弹出一个结点,就弹进该节点的左右孩子
            if(i==0)result=node->val;//记录最后一行第一个元素
             if (node->left) que.push(node->left);
                if (node->right) que.push(node->right);
        }
    }
    return result;

    }
};

112.路径总和

题目:112. 路径总和 - 力扣(LeetCode)

给定一个二叉树和一个目标和,判断该树中是否存在根节点到叶子节点的路径,这条路径上所有节点值相加等于目标和。

说明: 叶子节点是指没有子节点的节点。

示例: 给定如下二叉树,以及目标和 sum = 22,

返回 true, 因为存在目标和为 22 的根节点到叶子节点的路径 5->4->11->2。

 

递归法 

优先考虑深度优先遍历,前中后序都没有区别,因为没有中的处理逻辑。

累加判断是否等于的写法有点麻烦,可以用递减法,如果count等于0就说明找到了。

class Solution {
public:
    bool traversal(TreeNode*cur,int count)
    {
        if(!cur->left&&!cur->right&&count==0)return true;//遇到叶子节点且count为0
        if(!cur->left&&!cur->right)return false;//遇到叶子节点且count不为0

        if(cur->left)
        {
            count-=cur->left->val;
            if(traversal(cur->left,count))return true;//如果从下一层递归里得到1返回1
            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==NULL)return false;
       return  traversal(root,targetSum-root->val);
    }
};

 迭代法可以用栈模拟回溯。

113.路径总和Ⅱ

113. 路径总和 II - 力扣(LeetCode)

给定一个二叉树和一个目标和,找到所有从根节点到叶子节点路径总和等于给定目标和的路径。

说明: 叶子节点是指没有子节点的节点。

要遍历整棵树,所以递归函数没有返回值。 

class Solution {
public:
    vector<vector<int>>result;
    vector<int>path;
    void traversal(TreeNode*cur,int count)
    {
        if(!cur->left&&!cur->right&&count==0)
        {
            result.push_back(path);
            //找到一条路径
            return;
        }

        if(!cur->left&&!cur->right)return;

        if(cur->left)//左
        {
            count-=cur->left->val;
            path.push_back(cur->left->val);
            traversal(cur->left,count);
            //回溯
            count+=cur->left->val;
            path.pop_back();
        }

        if(cur->right)//左
        {
            count-=cur->right->val;
            path.push_back(cur->right->val);
            traversal(cur->right,count);
            //回溯
             count+=cur->right->val;
            path.pop_back();
        }
        return;


    }
    vector<vector<int>> pathSum(TreeNode* root, int targetSum) {
        result.clear();
        path.clear();
        if(root==NULL)return result;
        path.push_back(root->val);
        traversal(root,targetSum-root->val);
        return result;
        

    }
};

也比较简单。

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

题目:106. 从中序与后序遍历序列构造二叉树 - 力扣(LeetCode)

 之前看过从中序和后序以及前序和中序构造二叉树的书本例子,所以本题理解起来不难,就是代码没有切实打过。中序是比较重要的,因为可以帮助我们区分左右子树。

来看一下一共分几步:

  • 第一步:如果数组大小为零的话,说明是空节点了。

  • 第二步:如果不为空,那么取后序数组最后一个元素作为节点元素。

  • 第三步:找到后序数组最后一个元素在中序数组的位置,作为切割点

  • 第四步:切割中序数组,切成中序左数组和中序右数组 (顺序别搞反了,一定是先切中序数组)

  • 第五步:切割后序数组,切成后序左数组和后序右数组

  • 第六步:递归处理左区间和右区间

 

代码注意点,切割中序数组时,首先从后序数组找到了最后一个元素,就是根节点,在中序数组找到,左右分割成左中序和右中序。再根据左右中序的大小,在后序数组切割相应大小的元素, 分割前部分为左后序后部分为右后序。以此类推,递归构造二叉树。

代码

class Solution {
private:
    TreeNode*traversal(vector<int>& inorder,vector<int>& postorder)
    {
        if(postorder.size()==0)return NULL;
        int rootvalue=postorder[postorder.size()-1];//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;
        }

        vector<int>leftinorder(inorder.begin(),inorder.begin()+delimiterIndex);//切割中序数组,左闭右开写法
        vector<int>rightinorder(inorder.begin()+delimiterIndex+1,inorder.end());//注意这里是+1!

        postorder.resize(postorder.size()-1);//移除后序数组最后一个元素

        //切割后序数组,注意后序和中序大小一样,所以可以以上步求得的左右中序数组大小作为分割
        vector<int>leftpostorder(postorder.begin(),postorder.begin()+leftinorder.size());
        vector<int>rightpostorder(postorder.begin()+leftinorder.size(),postorder.end());

        root->left=traversal(leftinorder,leftpostorder);//传入新的左中序和左后序,继续构造左右子树
        root->right=traversal(rightinorder,rightpostorder);
        
        return root;
    }
public:
    TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder) {
        if(inorder.size()==0||postorder.size()==0)return NULL;
        return traversal(inorder,postorder);

    }
};

今天的还行吧。没有特别难,基本都能自己写出来,但是细节还要多注意。

 

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

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

相关文章

InternVL 微调实践

任务 follow 教学文档和视频使用QLoRA进行微调模型&#xff0c;复现微调效果&#xff0c;并能成功讲出梗图. 复现过程 参考教程部署&#xff1a;https://github.com/InternLM/Tutorial/blob/camp3/docs/L2/InternVL/joke_readme.md 训练 合并权重&&模型转换 pyth…

多旋翼无人机“仿鸟类”精确拦截飞行目标,助力低空安全

摘要&#xff1a; 使用低成本携带捷联式相机的无人机拦截低空入侵目标是一种具有竞争力的选择。然而&#xff0c;非合作目标的恶意机动和摄像头的耦合使得这项任务充满挑战。为了解决这个问题&#xff0c;提出了一种基于比例导引且具有视场保持能力的基于图像的视觉伺服&#x…

【d52】【Java】【力扣】19.删除链表的倒数第N个节点

思路 1.遍历数组,统计个数&#xff0c;记为total 2.计算出需要被删除的节点 是正数第几个&#xff0c;记做order 3.遍历到order-1,,然后执行删除下一个节点的操作 这里遍历到order-1&#xff0c;是因为想要删除一个节点&#xff0c;需要操作的是它前一个节点的next 代码 /…

JAVA使用Scanner类的nextLint()方法无法正确读取中文。

在练习的时候&#xff0c;我发现我使用Scanner类的nextLint&#xff08;&#xff09;方法无法正确读取到中文了。检查了我的idea编辑器&#xff0c;用的编码格式也是”utf-8“。所以编码格式没有问题。 问题如下棉两张图所示&#xff0c;我输入宝马后&#xff0c;控制台不打印…

助力申报“山东省首台套技术装备”,安畅检测提供第三方检测服务

9月24日&#xff0c;山东省工业和信息化厅发布了《关于组织2024年度山东省首台&#xff08;套&#xff09;技术装备认定工作的通知》。 《通知》中对申报范围、申请条件及申报程序做出了明确规定&#xff0c;并在附件中对申请材料做出了要求。 ★检测报告要求 在《通知》附件…

面试前需要准备什么?

面试前的准备是一个细致且全面的过程&#xff0c;它不仅关乎到你能否在面试中展现出最佳状态&#xff0c;还直接影响到你能否成功获得心仪的职位。以下是一个较为详尽的、接近2000字的面试前准备指南&#xff1a; 一.自我评估与定位 1.深入了解自己 在准备面试之前&#xff…

再谈智慧园区

随着AI的兴起&#xff0c;其影响力将渗透到各行各业。产业园区也不例外。特别是江园科技智慧园区在园区运营上&#xff0c;从早期的信息化&#xff0c;到数字化、智能化&#xff0c;智慧园区是一个不可回避的话题。 01 江园科技智慧园区 无论名称或概念怎么办&#xff0c;产…

Halcon实用系列1-识别二维条码

在做项目时&#xff0c;之前使用的是某康的智能读码器&#xff0c;综合考虑成本&#xff0c;可通过相机拍照来读取图片的二维码&#xff0c;我这边用Halcon来实现。 Halcon代码如下&#xff1a; *创建模型 create_data_code_2d_model(Data Matrix ECC 200, [], [], DataCodeH…

微信小程序map组件自定义气泡真机不显示

最近遇到一个需求需要使用uniapp的map自定义气泡 &#xff0c;做完之后发现在模拟器上好好的&#xff0c;ios真机不显示&#xff0c;安卓页数时好时不好的 一番查询发现是小程序的老问题了&#xff0c;网上的方法都试了也没能解决 后来看到有人说用nvue可以正常显示&#xff0c…

数据结构 ——— 顺序表oj题:编写函数,合并两个有序数组

目录 题目要求 代码实现 题目要求 nums1 和 nums2 是两个升序的整型数组&#xff0c;另外有两个整数 m 和 n 分别代表 nums1 和 nums2 中的元素个数 要求合并 nusm2 到nums1 中&#xff0c;使合并后的 nums1 同样按升序顺序排列 最终&#xff0c;合并后的数组不应由函数返…

基于Hive和Hadoop的招聘分析系统

本项目是一个基于大数据技术的招聘分析系统&#xff0c;旨在为用户提供全面的招聘信息和深入的职位市场分析。系统采用 Hadoop 平台进行大规模数据存储和处理&#xff0c;利用 MapReduce 进行数据分析和处理&#xff0c;通过 Sqoop 实现数据的导入导出&#xff0c;以 Spark 为核…

Text-to-SQL方法研究

1、面临的挑战 自然语言问题往往包含复杂的语言结构,如嵌套语句、倒装句和省略等,很难准确映射到SQL查询上。此外,自然语言本身就存在歧义,一个问题可能有多种解读。消除歧义需要深入的语言理解能力以及融入上下文和领域知识。 要生成正确的SQL查询,文本到SQL系统需要全面理解…

webpack 4 的 30 个步骤构建 react 开发环境

将 react 和 webpack4 进行结合&#xff0c;集 webpack 的优势于一身&#xff0c;从 0 开始构建一个强大的 react 开发环境。 其实很多人都有 一看就会&#xff0c;一做就废 的特点(当然也包括我在内)&#xff0c;这个时候&#xff0c;你需要制定一个略微详细的计划&#xff0…

Redis的基础认识与在ubuntu上的安装教程

来自Redis的自我介绍 我是Redis&#xff0c;一个中间件&#xff0c;职责是把数据存储在内存上&#xff0c;因此可以作为数据库、缓存、消息队列等场景使用。由于可以把数据存储在内存上&#xff0c;因此江湖人称快枪手 1.redis的功能特性 &#xff08;1&#xff09;数据在内存…

9.3 Linux_I/O_文件I/O相关函数

打开与关闭 1、打开文件 int open(const char *pathname, int flags); int open(const char *pathname, int flags, mode_t mode);返回值&#xff1a;成功返回文件描述符&#xff0c;失败返回EOF pathname&#xff1a;文件路径 flags&#xff1a;标志&#xff0c;其中O_RDO…

深入浅出CSS盒子模型

“批判他人总是想的太简单 剖析自己总是想的太困难” 文章目录 前言文章有误敬请斧正 不胜感恩&#xff01;什么是盒子模型&#xff1f;盒子模型的组成部分详解1. 内容区&#xff08;Content&#xff09;2. 内边距&#xff08;Padding&#xff09;3. 边框&#xff08;Border&am…

『功能项目』下载Mongodb【81】

下载网址&#xff1a;Download MongoDB Community Server | MongoDB 点击安装即可 选择Custom 此时安装已经完成 桌面会创建图标 检查是否配置好MongoDB 输入cmd命令行 Windows键 R 打开命令行 输入cmd 复制安装路径 复制data路径 如果输出一大串代码即配置mongdb成功

Mysql高级篇(中)——锁机制

锁机制 一、概述二、分类1、读锁2、写锁★、FOR SHARE / FOR UPDATE&#xff08;1&#xff09;NOWAIT&#xff08;2&#xff09;SKIP LOCKED&#xff08;3&#xff09;NOWAIT 和 SKIP LOCKED 的比较 ★、 脏写3、表级锁之 S锁 / X锁&#xff08;1&#xff09;总结&#xff08;2…

免费视频无损压缩工具+预览视频生成工具

视频无损压缩工具 功能与作用 &#xff1a;视频无损压缩工具是一种能够减少视频文件大小&#xff0c;但同时保持视频质量的工具。它通过先进的编码技术和算法&#xff0c;有效降低视频文件的存储空间&#xff0c;同时保证视频的清晰度和观感。这对于需要分享或存储大量视频内容…

ZLMediaKit快速上手【保姆级简单快速版】

一、前言 1、ZLMediaKit使用场景 最近在写一个摄像头检测的项目&#xff0c;其中需要做拉流测试&#xff0c;但是摄像头数量不够用&#xff0c;如果直接重复拉流可能会出现问题&#xff0c;使用ZLMediaKit&#xff08;一个基于C11的高性能运营级流媒体服务框架&#xff09;可…