day18 找树左下角的值 路径总和 路径总和Ⅱ 从中序与后序遍历序列构造二叉树 从前序与中序遍历序列构造二叉树

题目1:513 找树左下角的值

题目链接:513 找树左下角的值

题意

找出二叉树的最底层  最左边节点的值     (假设二叉树中至少有1个节点)

最底层节点确保是深度最大的叶子节点,最左边的节点却不一定是左孩子

递归遍历

深度最大的叶子节点最左侧的值,使用前序(中左右)中序(左中右)后序(左右中)遍历均可,因为都是先遍历左,后遍历右,这样确保先遍历左节点,如果左节点满足,就会直接放入result中,如果没有左节点,才会遍历同层的右节点  这样保证遍历的是二叉树的深度最大的叶子节点的最左边的值

递归三部曲

1)确定递归函数的参数和返回值

2)确定终止条件

3)确定单层递归逻辑

代码

/*** 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 maxdepth = INT_MIN;//记录最大深度int result = 0;//记录最大深度对应的节点数值void traversal(TreeNode* node,int depth){//终止条件  叶子节点if(node->left==NULL && node->right==NULL){if(maxdepth < depth){maxdepth = depth;result = node->val;}}//单层递归逻辑if(node->left){depth++;traversal(node->left,depth);depth--;//回溯}if(node->right){depth++;traversal(node->right,depth);depth--;//回溯}}int findBottomLeftValue(TreeNode* root) {int depth = 0;traversal(root,depth);return result; }
};
逻辑

如果右节点的值大于本层左节点的值,会改变result吗?

Answer:并不会

层序遍历

记录最后一层遍历到的第一个节点的值就可

代码

/*** 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 findBottomLeftValue(TreeNode* root) {queue<TreeNode*> que;int result = 0;if(root!=NULL) 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;}
};

题目2:112 路径总和

题目链接:112 路径总和

题意

判断是否存在:根节点到叶子节点的路径上所有节点值相加等于目标和targetsum

如果存在,返回true,如果不存在,返回false

递归

前序遍历,中序遍历,后序遍历均可,因为没有中节点的处理逻辑

递归三部曲:

1)确定递归函数的返回值和参数   只要有1条路径就行,返回true  所以递归函数需要返回值

2)确定终止条件

3)确定单层递归逻辑

代码

/*** 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:bool traversal(TreeNode* node,int count){//终止条件  遇到叶子节点就判断一下if(node->left==NULL && node->right==NULL && count==0) return true;if(node->left==NULL && node->right==NULL && count!=0) return false;//单层递归逻辑if(node->left){count -= node->left->val;if(traversal(node->left,count)) return true;count += node->left->val;}if(node->right){count -= node->right->val;if(traversal(node->right,count)) return true;count += node->right->val;}return false;}bool hasPathSum(TreeNode* root, int targetSum) {if(root==NULL) return false;return traversal(root,targetSum-root->val);}
};

迭代遍历

使用栈的方法代替递归遍历  栈中放入两个值:当前节点  当前总和

代码

/*** 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:bool hasPathSum(TreeNode* root, int targetSum) {if(root==NULL) return false;stack<pair<TreeNode*,int>> st;st.push(pair<TreeNode*,int>(root,root->val));//st的第二个位置处的整数做加加操作while(!st.empty()){pair<TreeNode*,int> node = st.top();st.pop();if(node.first->left==NULL && node.first->right==NULL && node.second==targetSum) return true;if(node.first->right) st.push(pair<TreeNode*,int>(node.first->right,node.second+node.first->right->val));//左if(node.first->left) st.push(pair<TreeNode*,int>(node.first->left,node.second+node.first->left->val));//右}return false;}
};

题目3:113 路径总和Ⅱ

题目链接:路径总和Ⅱ

题意

找出所有根节点到叶子节点的路径总和等于targetsum的路径

递归遍历

要遍历所有的节点,所以递归函数不需要返回值

代码

/*** 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:vector<int> path;vector<vector<int>> result;void traversal(TreeNode* node,int count){//终止条件if(node->left==NULL && node->right==NULL && count==0){result.push_back(path);return;}//单层递归逻辑if(node->left){path.push_back(node->left->val);count -= node->left->val;traversal(node->left,count);count += node->left->val;path.pop_back();}if(node->right){path.push_back(node->right->val);count -= node->right->val;traversal(node->right,count);count += node->right->val;path.pop_back();}}vector<vector<int>> pathSum(TreeNode* root, int targetSum) {if(root==NULL) return result;path.push_back(root->val);traversal(root,targetSum-root->val);return result;}
};

迭代遍历较为复杂

题目4:106 从中序与后序遍历序列二叉构造树

题目链接:106 从中序遍历与后序遍历序列构造二叉树

题意

根据中序遍历数组inorder和后序遍历数组postorder构造二叉树

递归

递归三部曲:

1)确定递归函数的参数和返回值

2)确定终止条件

3)确定单层递归逻辑

数组

代码

/*** 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* buildTree(vector<int>& inorder, vector<int>& postorder) {//终止条件if(postorder.size()==0) return NULL;//单层递归逻辑//中节点int rootvalue = postorder[postorder.size()-1];TreeNode* root = new TreeNode(rootvalue);if(postorder.size()==1) return root;//叶子节点//寻找中序数组的切割点indexint index;for(index=0;index<inorder.size();index++){if(inorder[index]==rootvalue){break;}}//切割中序数组(左中右)  左闭右开  循环不变量//中序左vector<int> inorderleft(inorder.begin(),inorder.begin()+index);//中序右  //注意抛除掉中节点vector<int> inorderright(inorder.begin()+index+1,inorder.end());//切割后序数组(左右中)//去除掉中节点postorder.resize(postorder.size()-1);//后序左vector<int> postorderleft(postorder.begin(),postorder.begin()+inorderleft.size());//后序右vector<int> postorderright(postorder.begin()+inorderleft.size(),postorder.end());//左子树root->left = buildTree(inorderleft,postorderleft);//右子树root->right = buildTree(inorderright,postorderright);return root;}
};
下标(节省空间复杂度)

代码

/*** 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* traversal(vector<int>& inorder,int inorderbegin,int inorderend,vector<int>& postorder,int postorderbegin,int postorderend){//终止条件if(postorderbegin == postorderend) return NULL;//单层递归逻辑//中节点int rootvalue = postorder[postorderend-1];TreeNode* root = new TreeNode(rootvalue);if(postorderend-postorderbegin==1) return root;//中序数组切割点int index;for(index=inorderbegin;index<inorderend;index++){if(inorder[index]==rootvalue){break;}}//切割中序数组(左中右)  左闭右开//中序左int inorderleftbegin = inorderbegin;int inorderleftend = index;//注意使用的是索引的方法,所以这里直接使用索引//中序右  抛除掉中节点int inorderrightbegin = index + 1;int inorderrightend = inorderend;//切割后序数组(左右中)  左闭右开//后序左int postorderleftbegin = postorderbegin;int postorderleftend = postorderbegin + (inorderleftend - inorderleftbegin);//由于后序是通过中序左的的大小得到的,所以前面要加上postorderbegin//后序右  抛除掉中节点int postorderrightbegin= postorderbegin + (inorderleftend - inorderleftbegin);int postorderrightend = postorderend - 1;// cout<<"inorderleft:";//中序左// for(int i=inorderleftbegin;i<inorderleftend;i++){//     cout<<inorder[i]<<" ";// }// cout<<endl;// cout<<"inorderright:";//中序右// for(int j=inorderrightbegin;j<inorderrightend;j++){//     cout<<inorder[j]<<" ";// }// cout<<endl;// cout<<"postorderleft:";//后序左// for(int i=postorderleftbegin;i<postorderleftend;i++){//     cout<<postorder[i]<<" ";// }// cout<<endl;// cout<<"postorderright:";//后序右// for(int i=postorderrightbegin;i<postorderrightend;i++){//     cout<<postorder[i]<<" ";// }// cout<<endl;root->left = traversal(inorder,inorderleftbegin,inorderleftend,postorder,postorderleftbegin,postorderleftend);root->right = traversal(inorder,inorderrightbegin,inorderrightend,postorder,postorderrightbegin,postorderrightend);return root;}TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder) {//终止条件if(postorder.size()==0) return NULL;return traversal(inorder,0,inorder.size(),postorder,0,postorder.size());  //左闭右开}
};

题目5:105 从前序与中序遍历序列构造二叉树

题目链接:105 从前序与中序遍历序列构造二叉树

题意

根据前序遍历数组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* buildTree(vector<int>& preorder, vector<int>& inorder) {//终止条件//空节点if(preorder.size()==0) return NULL;//单层递归逻辑//中节点int rootvalue = preorder[0];TreeNode* root = new TreeNode(rootvalue);if(preorder.size()==1) return root;//叶子节点//中序数组切割点int index;for(index=0;index<inorder.size();index++){if(inorder[index]==rootvalue){break;}}//切割中序数组(左中右)   左闭右开//中序左vector<int> inorderleft(inorder.begin(),inorder.begin()+index);//中序右   抛除掉中节点元素vector<int> inorderright(inorder.begin()+index+1,inorder.end());//切割前序数组(中左右)  左闭右开//抛除掉中节点元素//前序左vector<int> preorderleft(preorder.begin()+1,preorder.begin()+1+inorderleft.size());//前序右vector<int> preorderright(preorder.begin()+1+inorderleft.size(),preorder.end());root->left = buildTree(preorderleft,inorderleft);root->right = buildTree(preorderright,inorderright);return root;}
};
下标

代码

/*** 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* traversal(vector<int>& preorder, int preorderbegin, int preorderend, vector<int>& inorder,int inorderbegin, int inorderend){//终止条件if(preorderend-preorderbegin==0) return NULL;//单层递归逻辑//中节点int rootvalue = preorder[preorderbegin];TreeNode* root = new TreeNode(rootvalue);//叶子节点if(preorderend-preorderbegin==1) return root;//中序数组切割点int index;for(index=0;index<inorderend;index++){if(inorder[index]==rootvalue){break;}}//切割中序数组 左中右//中序左int inorderleftbegin = inorderbegin;int inorderleftend = index;//中序右  抛除中节点indexint inorderrightbegin = index + 1;int inorderrightend = inorderend;//切割前序数组  中左右//前序左  抛除中节点preorderbeginint preorderleftbegin = preorderbegin + 1;int preorderleftend = preorderbegin + 1 + (index - inorderbegin);//前序右  int preorderrightbegin = preorderbegin + 1 + (index - inorderbegin);int preorderrightend = preorderend;root->left = traversal(preorder,preorderleftbegin,preorderleftend,inorder,inorderleftbegin,inorderleftend);root->right = traversal(preorder,preorderrightbegin,preorderrightend,inorder,inorderrightbegin,inorderrightend);return root;}TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {if(preorder.size()==0) return NULL;return traversal(preorder,0,preorder.size(),inorder,0,inorder.size());}
};

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

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

相关文章

docker使用nginx部署vue刷新页面404

docker使用nginx部署vue刷新页面404 从docker内部复制出来的配置文件是这样的&#xff0c;但是刷新页面之后就显示404&#xff0c;关键是我两个前端项目都是用的这一个配置文件&#xff0c;但是只有一个项目出现刷新浏览器显示404的问题&#xff0c;这给我搞懵了&#xff01;&…

【dayjs】类型“Dayjs”上不存在属性“isSameOrAfter”

dayjs中有一些方法是需要使用插件后才能使用&#xff0c;默认情况下&#xff0c;Day.js只提供核心代码&#xff0c;没有安装插件。 解决方法&#xff1a; import dayjs from dayjs;import isSameOrAfter from dayjs/plugin/isSameOrAfter;dayjs.extend(isSameOrAfter);再次使…

AI嵌入式K210项目(5)-串口通讯

文章目录 前言一、什么是UART&#xff1f;二、K210的UART三、实验过程总结 前言 串口通讯是平时大家进行调试最常用的方法&#xff0c;嵌入式应用通常要求一个简单的并且占用系统资源少的方法来传输数据。通用异步收发传输器 (UART)即可以满足这些要求&#xff0c;它能够灵活地…

odoo16 权限继承修改字段显示2

odoo16 权限继承修改字段显示2 上次文章写道:最近在搭建的一个服装批发中心使用的进销存一体化项目,由于客户文化水平低,不想在发货界面显示 好多无用功能,有些是有用的,有些是他不关心的。占在用户角度考虑,用不到的功能都是垃圾。有他们的道理。在隐藏的过程中,出现了…

2011 年考研数二真题解析

一、选择题 【01】【02】【03】【04】【05】【06】【07】【08】 二、填空题 【09】【10】【11】【12】【13】【14】 三、解答题 【15】【16】【17】【18】【19】【20】【21】【22】【23】

运筹说 第90期 | 网络计划-图解评审法

前述章节的网络计划方法主要研究以时间为主要参数的确定型网络模型&#xff0c;其中的概率型网络模型也只讨论工作公式的不确定性&#xff0c;并没有对事项或工作的不确定性进行讨论。由于这类网络模型的建立有严格的规则&#xff0c;大量研究与开发类计划尚无法表达。因从本期…

vue中el-radio无法默认选中

页面上不生效&#xff0c;默认什么都不选中 <el-radio-group v-model"queryParams.videoUrlType"><el-radio :label"1">本地上传</el-radio><el-radio :label"2">外部链接</el-radio> </el-radio-group>da…

污水处理厂能耗分析系统,高效节能保护环境的利器

在城市化发展中&#xff0c;水污染问题也愈发凸显&#xff0c;在污水处理过程中&#xff0c;所产生的能源相对较多&#xff0c;企能源消耗的量就比较大&#xff0c;所以成本就会较高。因此&#xff0c;应对污水处理的具体情况需要进行深入分析与研究&#xff0c;明确具体消耗情…

Lamp架构从入门到精通

系列文章目录 lnmp架构 lnmp架构-nginx负载均衡以及高可用 系列文章目录一、源码编译configure(检测预编译环境是否可行)makemake install优化关闭Debug 二、 nginx负载均衡三、nginx的高并发nginx work数量的设定nginx work进程与cpu的静态绑定压力测试nginx高并发修改操作系…

Spring AOP 源码分析

【阅读前提】&#xff1a; 需了解AOP注解开发流程&#xff1a;链接 一、注解 EnableAspectJAutoProxy 在配置类中添加注解EnableAspectJAutoProxy&#xff0c;便开启了AOP&#xff08;面向切面编程&#xff09; 功能。此注解也是了解AOP源码的入口。 EnableAspectJAutoProxy…

编码技巧:如何在Golang中高效解析和生成XML

编码技巧&#xff1a;如何在Golang中高效解析和生成XML 引言Golang中的XML基础解析XML文件生成XML文件错误处理和调试高级技巧和最佳实践总结 引言 在当今数据驱动的编程世界中&#xff0c;有效地处理各种数据格式是每个开发人员必备的技能之一。其中&#xff0c;XML&#xff…

【人工智能:现代方法】第19章:样例学习

智能体学习&#xff08;learning&#xff09;&#xff1a;一个智能体通过对世界进行观测来提高它的性能机器学习&#xff08;machine learning&#xff09;&#xff1a;智能体是一台计算机 —— 一台计算机观测到一些数据&#xff0c;基于这些数据构建一个模型&#xff08;mode…

并发编程之三大特性及JMM内存模型

目录 原子性 如何保证原子性 可见性 如何保证可见性 有序性 如何保证有序性 Java内存模型(JMM内存模型) Java内存模型的一些关键概念&#xff1a; 主内存与工作内存交互协议 Java内存模型通过以下手段来确保多线程程序的正确性&#xff1a; 锁机制 volatile volat…

1-数组-有效的数独

这是数组的第一题&#xff0c;从现在开始开启数组篇章。力扣链接。 请你判断一个 9 x 9 的数独是否有效。只需要 根据以下规则 &#xff0c;验证已经填入的数字是否有效即可。 数字 1-9 在每一行只能出现一次。数字 1-9 在每一列只能出现一次。数字 1-9 在每一个以粗实线分隔的…

Fpga开发笔记(二):高云FPGA发开发软件Gowin和高云fpga基本开发过程

若该文为原创文章&#xff0c;转载请注明原文出处 本文章博客地址&#xff1a;https://hpzwl.blog.csdn.net/article/details/135620590 红胖子网络科技博文大全&#xff1a;开发技术集合&#xff08;包含Qt实用技术、树莓派、三维、OpenCV、OpenGL、ffmpeg、OSG、单片机、软硬…

【Redis配置】Linux下的Redis安装配置

压缩包方式的Redis下载与安装 进入官网 Redis官网&#xff1a;https://redis.io/download/ 往下翻可以找到其他版本的Redis&#xff0c;或者访问https://download.redis.io/releases/查找自己所需Redis版本。 下载自己所需版本 此处我选择下载的是6.2.14版本 上传到Linux…

墙地砖外形检测的技术方案-图像分割

基础原理 由于对碗口进行缺口检测&#xff0c;因此只需要碗口的边界信息。得到陶瓷碗区域填充后的图像&#xff0c;对图像进行边缘检测。这是属于图像分割中的内容&#xff0c;在图像的边缘中&#xff0c;可以利用导数算子对数字图像求差分&#xff0c;将边缘提取出来。 案例…

Vue:将以往的JQ页面,重构成Vue组件页面(组件化编码大致流程)

一、实现静态组件 组件要按照功能点拆分&#xff0c;命名不要与HTML元素冲突。 1、根据UI提供的原型图&#xff0c;进行结构设计&#xff0c;结构设计的粒度以是否方便给组件起名字为依据。并梳理好对应组件的层级依赖关系。 2、设计好结构后&#xff0c;开始写对应的组件&am…

pl/sql程序块的使用

-- Created on 2024-01-15 by ADMINISTRATOR declare -- Local variables hererecord_tablename varchar2(100);---test_record表名record_StartNo integer(19);---test_record开始编号temp_No integer(19);maxnbbh integer(19);nCnt integer : 20;fi…

家用小型洗衣机哪款性价比高?好用的内衣洗衣机推荐

现在大多数的上班族&#xff0c;面临的都是早九晚六的工作&#xff0c;而且工作完下班回家还是面对各种各样的家务&#xff0c;特别是清洗需要换洗的洗衣&#xff0c;属实是有点辛苦了。可能很多人为了方便&#xff0c;每次洗衣服的都是把一堆衣服直接丢进洗衣机&#xff0c;直…