算法力扣刷题记录 四十二【101. 对称二叉树、100.相同的树、572.另一个树的子树】

前言

二叉树篇,开始对二叉树操作练习。
记录 四十二【101. 对称二叉树】。
继续。


一、题目阅读

给你一个二叉树的根节点 root , 检查它是否轴对称

示例 1:
在这里插入图片描述

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

示例 2:
在这里插入图片描述

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

提示:

树中节点数目在范围 [1, 1000] 内
-100 <= Node.val <= 100

进阶:你可以运用递归和迭代两种方法解决这个问题吗?


二、尝试实现

思路一

先用递归试一下。核心:判断轴对称的标准是什么?

递归:自己调用自己。暂时没找到重复的逻辑

  • 判断left== right?进入到子树,不正确。
  • 左子树走左右中,右子树走右左中。序列相等?但这是对整个树。进入到子树,也不对。

思路二

改变用迭代法。用层序遍历。
获得层序结果之后,判断每一层是偶数且reverse之后相等。但对于示例二,不成立,因为空指针被排除。
思路不成立。

总结:虽然知道要找对称,但是统一判断对称的标准不会


三、参考思路

参考思路链接

学习内容

  • 轴对称:根节点的左子树和右子树是否可以翻转相等? ,如何比较?
  • 从讲解获得正确思路:本次遍历需要根节点的左子树和根节点的右子树同时遍历。一次性遍历两个子树,才能判断两边节点相不相等。
    • 先传左子树的left和右子树的right,此时外侧节点判断相等;
    • 再传左子树的right和右子树的left,此时内侧节点判断相等;
    • 两者返回之后,同时都为true,说明对称。
  • 确定遍历顺序:左右中。处理完左孩子,再处理右孩子,把结果返回给中节点。
  • 尝试实现中思路不足之处:只处理根节点左子树,发现根节点右子树的顺序和左边不一样。用遍历顺序翻转,或者如何,都得不到统一的逻辑。

递归实现

每一个注释都是思路。

/*** 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 iscompare(TreeNode* left,TreeNode* right){ //两边同时遍历,所以两个参数。返回是否相等,用bool类型。//确定终止条件if(!left && !right) return true;    //同时为空,可以翻转else if(!left && right) return false; //一个空,一个不为空。肯定不等else if (!right && left) return false;//一个空,一个不为空。肯定不等else if(left->val != right->val) return false;//都不为空,但是值不等//都不为空,值相等。说明可以继续进行外侧比较、内侧比较,不用return。bool outside = iscompare(left->left,right->right);  //同时比较,解决了左右遍历顺序不一样bool inside = iscompare(left->right,right->left);return outside && inside;   //同时返回true。才能返回true}bool isSymmetric(TreeNode* root) {return iscompare(root->left,root->right);}
};

一个树(左子树)的遍历顺序是左右中,一个树(右子树)的遍历顺序是右左中。

迭代思路1

  • 同时处理根节点左子树和根节点右子树。和之前的遍历不一样。
  • 用队列结构:把要比较的两个节点同时放入队列中,再同时取出来。判断取出来的两个节点能否翻转。所以如果左右孩子有空,也需要放到队列里。
  • 用栈结构:还是要同时处理两个节点。有两个对象要做比较。 同时放进去,再同时取出来

迭代实现【队列结构】

栈结构一样。

/*** 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 isSymmetric(TreeNode* root) {if(!root) return false;queue<TreeNode*> que;que.push(root->left);//放入左子树que.push(root->right);//放入右子树while(!que.empty()){TreeNode* left = que.front(); que.pop();//取出比较对象中的左节点TreeNode* right = que.front();que.pop();//取出比较对象中的右节点if(!left && !right){    //都是空节点continue;}else if(!left || !right || left->val != right->val){return false;}que.push(left->left);que.push(right->right);que.push(left->right);que.push(right->left);}return true;}
};

总结【轴对称二叉树】:

  • 依然是遍历,不同在于:必须同时遍历两个子树。深入任何一个子树递归都是不对的。
  • 比较对象判断true的条件:同时空;或值相等。其余都是false。
  • 也不可以深入任何一个子树递归遍历,因为左边和右边顺序不一样。
  • 不是层序遍历。如果非得层序遍历:得出每一层结果,reverse之后看是否相等。如下(不推荐),上面的解答都很好。
/*** 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 isSymmetric(TreeNode* root) {vector<vector<int>> level;queue<TreeNode*> que;if(!root) return false;que.push(root);while(!que.empty()){int size = que.size();vector<int> vec;while(size--){TreeNode* cur = que.front();que.pop();if(cur){ //不是空节点que.push(cur->left);que.push(cur->right);vec.push_back(cur->val);}else{vec.push_back(INT_MIN);//因为节点的值【-100,100】。用一个最小值代表空。}}level.push_back(vec);}//获得层序遍历。包含空。空的数值借助INT_MIN代替。for(int i = 1;i < level.size();i++){vector<int> temp = level[i];reverse(temp.begin(),temp.end());if(temp != level[i]){return false;}}return true;}
};

题目练习

【100.相同的树】

一、题目

给你两棵二叉树的根节点 p 和 q ,编写一个函数来检验这两棵树是否相同。

如果两个树在结构上相同,并且节点具有相同的值,则认为它们是相同的。

示例 1:

输入:p = [1,2,3], q = [1,2,3]
输出:true

示例 2:

输入:p = [1,2], q = [1,null,2]
输出:false

示例 3:

输入:p = [1,2,1], q = [1,1,2]
输出:false

提示:

两棵树上的节点数目都在范围 [0, 100] 内
-10^4 <= Node.val <= 10^4

思路

判断两个树是否相同。结构相同且值相同。

  • 那么必须同时处理两个树,才有比较对象。只对一个树深入遍历/做什么操作,都是无用的 。
  • 和【101.对称二叉树】区别,比较对象。这里比较对象左孩子和左孩子比;右孩子和右孩子比。递归调用的参数给对。

代码实现

/*** 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 isSameTree(TreeNode* p, TreeNode* q) {if(!p && !q) return true;  //传入节点同时为空,可以对应else if(!p && q) return false;//一个空,另一个不是空。不可能对应。else if(p && !q) return false;//一个空,另一个不是空。不可能对应。else if(p->val != q->val) return false;//值不等,不可能对应。bool leftchild = isSameTree(p->left,q->left); bool rightchild = isSameTree(p->right,q->right);return leftchild && rightchild;}
};

【572.另一个树的子树】

题目

给你两棵二叉树 root 和 subRoot 。检验 root 中是否包含和 subRoot 具有相同结构和节点值的子树。如果存在,返回 true ;否则,返回 false 。

二叉树 tree 的一棵子树包括 tree 的某个节点和这个节点的所有后代节点。tree 也可以看做它自身的一棵子树。

示例 1:

输入:root = [3,4,5,1,2], subRoot = [4,1,2]
输出:true

示例 2:

输入:root = [3,4,5,1,2,null,null,null,null,0], subRoot = [4,1,2]
输出:false

提示:

root 树上的节点数量范围是 [1, 2000]
subRoot 树上的节点数量范围是 [1, 1000]
-10^4 <= root.val <= 10^4
-10^4 <= subRoot.val <= 10^4

思路

(1)子树也是判断两个树相等。可以用【100.题代码实现】解决相等判断。
(2)但是得在root中找到等于subRoot根节点值的节点,作为子树的根节点。用层序遍历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:bool isSame(TreeNode* rootnode,TreeNode* subRootnode){if(!rootnode && !subRootnode) return true;else if(!rootnode && subRootnode) return false;else if(rootnode && !subRootnode) return false;else if(rootnode->val != subRootnode->val) return false;bool leftchild = isSame(rootnode->left,subRootnode->left);bool rightchild = isSame(rootnode->right,subRootnode->right);return leftchild && rightchild;}bool isSubtree(TreeNode* root, TreeNode* subRoot) {//先找到和subRoot值相等的节点,才有可能相等。得遍历root找到和subRoot值相等的节点,可能作为子树的根节点//用层序遍历queue<TreeNode*> que;que.push(root);while(!que.empty()){int size = que.size();while(size--){TreeNode* cur = que.front();que.pop();if(cur->val == subRoot->val){bool subtree = isSame(cur,subRoot);if(subtree) return true;}if(cur->left) que.push(cur->left);if(cur->right) que.push(cur->right);}}return false;}
};

全文总结

核心:同时遍历两个树,确定比较对象。进行递归实现。

深入任何一个树遍历,都无法产生比较对象的双方。

(欢迎指正,转载标明出处)

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

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

相关文章

Pytest单元测试系列[v1.0.0][Pytest基础]

Pytest安装与配置 和Unittest一样&#xff0c;Pytest是另一个Python语言的单元测试框架&#xff0c;与Unittest相比它的测试用例更加容易编写、运行方式更加灵活、报错信息更加清晰、断言写法更简洁并且它可以运行有unittest和nose编写的测试用例。 Pytest 安装 启动命令行&…

【Pytorch】Conda环境下载慢换源/删源/恢复默认源

文章目录 背景临时换源永久换源打开conda配置condarc换源执行配置 命令行修改源添加源查看源 删源恢复默认源使用示范 背景 随着实验增多&#xff0c;需要分割创建环境的情况时有出现&#xff0c;在此情况下使用conda create --name xx python3.10 pytorch torchvision pytorc…

uni-app三部曲之二: 封装http请求

1.引言 前面一篇文章写了使用Pinia进行全局状态管理。 这篇文章主要介绍一下封装http请求&#xff0c;发送数据请求到服务端进行数据的获取。 感谢&#xff1a; 1.yudao-mall-uniapp: 芋道商城&#xff0c;基于 Vue Uniapp 实现&#xff0c;支持分销、拼团、砍价、秒杀、优…

电脑自动重启是什么原因呢?99%人都不知道的解决办法,直接打破循环

当你的电脑突然毫无预警地自动重启&#xff0c;不仅打断了工作流程&#xff0c;还可能导致未保存的数据丢失&#xff0c;这无疑是一件令人沮丧的事情。那么&#xff0c;电脑自动重启是什么原因呢&#xff1f;有什么方法可以解决呢&#xff1f;别担心&#xff0c;在大多数情况下…

docker-2

27.构建python应用镜像-dockerfile实践项目 1.基于官方的镜像&#xff0c;构建python代码运行环境 dockerfile 2.运行镜像&#xff0c;开启一个读写的容器空间&#xff08;定制操作&#xff0c;将代码丢进去&#xff0c;运行调试&#xff09; 3.提交这个变化的容器层数据&#…

cal命令

1、命令详解&#xff1a; cal&#xff08;全称&#xff1a;Calendar&#xff09;该命令用来显示当前日历或者指定日期的公历。 2、官方参数&#xff1a; -1, --one 仅显示当前月份&#xff08;默认&#xff09;-3, --three 显示上个月、当前月和下个月-s, --sunday…

谷粒商城P85发布商品时规格参数不显示问题

P85讲&#xff0c;发布商品&#xff0c;点击下一步之后&#xff0c;发现规格参数不显示 打开控制台发现报错forEach...错误 查了问题原因&#xff0c;发现返回的分组中个别组的关联属性(attrs)可能为null 所以这个时候&#xff0c;需要确保后端返回的attrs不能为null 方式1…

数据结构之顺序存储线性表实现详解与示例(C,C#,C++)

文章目录 一、顺序存储线性表的基本概念二、顺序存储线性表的实现1、数据结构定义2、初始化3、添加元素4、访问元素5、修改元素6、删除元素7、销毁 三、示例C语言示例C#语言示例C语言示例 顺序存储线性表是一种基本的数据结构&#xff0c;它将线性表的元素按照一定的顺序存放在…

每天一个数据分析题(四百二十五)- 单因素方差分析

关于下表&#xff0c;错误说法是&#xff08; &#xff09; A. 这是单因素方差分析的输出结果 B. 表中 F< F crit, 与 P-value 大于显著性水平是等价的 C. 表内组间均方差没有显著大于组内均方差 D. 由于组内SS数值显著大于组间SS&#xff0c;因此可以推断不同分类对于…

机器学习——决策树(笔记)

目录 一、认识决策树 1. 介绍 2. 决策树生成过程 二、sklearn中的决策树 1. tree.DecisionTreeClassifier&#xff08;分类树&#xff09; &#xff08;1&#xff09;模型基本参数 &#xff08;2&#xff09;模型属性 &#xff08;3&#xff09;接口 2. tree.Decision…

最新开源免费数字人工具

使用步骤更是简单到不行&#xff1a; 1. 输入图片&#xff1a;选择你想要生成动态视频的肖像图片。 2. 输入音频&#xff1a;提供与图片匹配的音频文件&#xff0c;EchoMimic会根据音频内容驱动肖像的动态效果。 3. 设置参数&#xff1a;一般保持默认设置即可&#xff0c;当然&…

《梦醒蝶飞:释放Excel函数与公式的力量》11.4 ISERROR函数

第11章&#xff1a;信息函数 第四节 11.4 ISERROR函数 11.4.1 简介 ISERROR函数是Excel中的一个信息函数&#xff0c;用于检查指定单元格或表达式是否产生错误。如果单元格或表达式产生任何类型的错误&#xff08;如N/A、VALUE!、REF!等&#xff09;&#xff0c;则返回TRUE&…

全开源TikTok跨境商城源码/TikTok内嵌商城+搭建教程/前端uniapp+后端

多语言跨境电商外贸商城 TikTok内嵌商城&#xff0c;商家入驻一键铺货一键提货 全开源完美运营 海外版抖音TikTok商城系统源码&#xff0c;TikToK内嵌商城&#xff0c;跨境商城系统源码 接在tiktok里面的商城。tiktok内嵌&#xff0c;也可单独分开出来当独立站运营 二十一种…

leetcode165.解密数字

题目表述&#xff1a; 这道题目和斐波那契数列以及跳台阶问题十分相似。 斐波那契数列&#xff1a;0、1、1、2、3、5, 8、13、21、34 …… leetcode跳台阶问题&#xff1a;1、1、2、3、5, 8、13、21、34....... 这类题目的特点都是第N项的结果等于前两项的和。 但是解密数…

【深度学习】图形模型基础(7):机器学习优化中的方差减少方法(1)

摘要 随机优化是机器学习中至关重要的组成部分&#xff0c;其核心是随机梯度下降算法&#xff08;SGD&#xff09;&#xff0c;这种方法自60多年前首次提出以来一直被广泛使用。近八年来&#xff0c;我们见证了一个激动人心的新进展&#xff1a;随机优化方法的方差降低技术。这…

车载测试资料学习和CANoe工具实操车载项目(每日直播)

每日直播时间&#xff1a;&#xff08;直播方式&#xff1a;腾讯会议&#xff09; 周一到周五&#xff1a;20&#xff1a;00-23&#xff1a;00 周六与周日&#xff1a;9&#xff1a;00-17&#xff1a;00 向进腾讯会议学习的&#xff0c;可以关注我并后台留言 直播内容&#xff…

Simscape物理建模步骤

为了介绍构建和仿真物理模型的步骤&#xff0c;这里以simulink自带示例模型Mass-Spring-Damper with Controller为例&#xff0c;下图为建立好的模型。 详细物理建模和仿真分析步骤如下&#xff1a; 步骤 1&#xff1a;使用 ssc_new 创建新模型 使用 ssc_new 是开始构建 Sims…

李彦宏所说的卷应用到底是什么?

李彦宏在2024世界人工智能大会上的发言强调了一个重要的观点&#xff0c;那就是在AI时代&#xff0c;技术的应用比技术本身更为关键。他所提出的“卷应用”而非“卷模型”&#xff0c;实际上是在呼吁业界关注AI技术的实际落地和价值创造&#xff0c;而不是单纯地在模型精度或规…

案例|LabVIEW连接S7-1200PLC

附带&#xff1a; 写了好的参考文章&#xff1a; 通讯测试工具和博图仿真机的连接教程【内含图文完整过程软件使用】 解决博图V15 V16 V17 V18等高版本和低版本在同款PLC上不兼容的问题 目录 前言一、准备条件二、步骤1. HslCommunicationDemo问题1&#xff1a;连接失败?问题…

Lingo学习(二)——线性规划基础、矩阵工厂

一、线性规划基础 &#xff08;一&#xff09;方法 ① 一个线性规划中只含一个目标函数。(两个以上是多目标线性规划,Lingo无法直接解) ② 求目标函数的最大值或最小值分别用max …或min …来表示。 ③ 以!开头,以;结束的语句是注释语句; ④ 线性规划和非线性规划的本质…