当前位置: 首页 > news >正文

代码随想录训练营第二十二天| 101.对称二叉树 100.相同的树

101.对称二叉树:

文档讲解:代码随想录|101.对称二叉树

视频讲解:新学期要从学习二叉树开始! | LeetCode:101. 对称二叉树_哔哩哔哩_bilibili

状态:已做出

思路:

这道题目我初始做的时候想着使用层序遍历来解决这个问题,但是后续做的时候发现出现很多问题,最重要的问题就是如果使用常规的层序遍历,那么队列里没有存储空指针,这样会导致后续遍历判断的时候出现错位,判断出错。后面看了文档的解法,原来使用队列的放书也不是层序遍历,文档给出了三种解法,一个递归,一个队列,一个栈,我就实现了递归和队列的方法,其实思想统一都是把树分为外侧和内测两边,每一边都进行遍历判断,递归就是遍历判断左边节点的左子树和右边节点的右子树,左边阶段的右子树和右边节点的左子树判断,这样深度遍历就可以实现内侧和内侧的遍历,外侧和外侧的遍历,队列就是每次让左边节点的左子树和右边节点的右子树一起入队,左边节点的右子树和右边节点的左子树一起入队,每次循环取出队列里的两个节点进行判断,出错有情况:两个判断的节点一个为空一个不为空,两个都非空但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 dfs(TreeNode* left, TreeNode* right) {if(!left && right) return false;//一个为空一个不为空说明不是对称,直接返回falseelse if(left && !right) return false;//一个为空一个不为空不是对称树,返回falseelse if(left && right && (left->val!=right->val)) return false;//两个不为空并且val值不相等说明不对称else if(!left && !right) return true;//两个都是空则是对称,返回true,没有子树所以没有必要进行以下的操作//这里不需要判断左右子树非空且val值也相等的情况,这种情况下不能返回true,要继续对这个节点的左右子树继续进行判断//下面设置两个遍历本别对左子树和右子树外侧和内测进行判断bool a1=dfs(left->left,right->right);//这个是对外侧的子树进行判断是否相等bool a2=dfs(left->right,right->left);//这个是对内测的子树进行判断是否相等return a1 && a2;//当左右子树都相等时才返回true}bool isSymmetric(TreeNode* root) {if(!root) return true;return dfs(root->left,root->right);}
};

队列迭代:

/*** 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 true;queue<TreeNode*>qu;//直接将根节点的左右子树一起放入队列中,后序入队都是成对插入,才能正确的外外、内内判断qu.push(root->left);qu.push(root->right);while(!qu.empty()) {//这里每次同时取出队列里的两个元素,都是成对取数TreeNode* left=qu.front();qu.pop();TreeNode* right=qu.front();qu.pop();if(!left && !right) continue;//当取出的两个节点都时空时,因为没有子树,所以没有必要进行下面的操作,直接continue/**这段代码把所有false的情况都包含了,因为上面的if如果条件是假,那么这两个节点至少有* 一个节点是非空的,那么我的条件是只要判断出一个节点是空整个节点就都是真,直接返回* false,如果两个都是非空,那么最后就判断这两个节点的val值是否相等了*/if((!left || !right || (left->val!=right->val))) return false;//最后把这个两个节点的左右子树对称的放入队列中,下面的插入顺序不能换,因为入队都是成对的qu.push(left->left);qu.push(right->right);qu.push(left->right);qu.push(right->left);}return true;}
};

遇到的困难:

这倒题目虽然是简单的题目,但是如果没使用好方法机会变得很难,当时我一股脑使用层序遍历就出现了很多问题,使用层序遍历没有考虑到会错位的情况。这道题目最简便的方式就是使用文档说的思想,把树分为内侧和外侧,把内侧和外侧分别进行判断,层序遍历要使用应该要把空给考虑进去。

收获:

通过这道题目的练习,学习到了这类题目的优解,没想到要使用内外侧思想来判断,这样思考之后这倒题目竟然一下简单很多,果然思想很重要啊。

100. 相同的树:

状态:已做出

思路:

这道题目可以把两棵树的根结点同时连在一个节点里,合并两棵树,这样结合题目意思就可以看出可以使用上一道题目的思路来解决了。不对合并后的整体树结合题意并不是单纯的判断是否对称,而是判断合并后的树的左右子树是否完全相同,那么我们需要改变判断对象,思路是一样的,把合并的树借节点看成内侧和外侧两种情况,判断对称是内侧和内侧判断,外侧和外侧判断,那么判断树相等则反过来外侧和内侧判断就行了。
代码如下(队列迭代):

/*** 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) {queue<TreeNode*>qu;//直接将这两树的根节点依次插入到队列里qu.push(p);qu.push(q);while(!qu.empty()) {TreeNode* left=qu.front();qu.pop();TreeNode* right=qu.front();qu.pop();if(!left && !right) continue;if(!left || !right || (left->val!=right->val)) return false;//上面的代码和上一道题目一模一样,就是下面的入对顺序不一样,因为要内测子树和外侧子子树成对,外侧子树和内侧子树成对qu.push(left->left);qu.push(right->left);qu.push(left->right);qu.push(right->right);}return true;}
};

遇到的困难:

这道题目思路和判断对称思路是一样的,只是代码的细节有点不一样而已,其中的难点就是思路,只要想到思路了代码和上一个题目大差不差。

收获:

这两道题目涉及的都是把树分为内外侧来分别判断,做两个相似的题目可以更加熟悉这类题目的思想,对这类题目有根深的印象。

http://www.xdnf.cn/news/412147.html

相关文章:

  • 综合实验二之grub2密文加密
  • (leetcode) 力扣100 10.和为K的子数组(前缀和+哈希)
  • 【Bootstrap V4系列】学习入门教程之 组件-模态框(Modal)
  • css 点击后改变样式
  • Megatron系列——张量并行
  • 我们来学mysql -- 安装8.4版本
  • 在CentOS 7上仅安装部署MySQL 8.0客户端
  • 将arduino开发的Marlin部署到stm32(3D打印机驱动)
  • 【GESP】C++三级练习 luogu-B2156 最长单词 2
  • NeurIPS 2025 截稿攻略
  • 无线传感器网络期末复习自整理资料(天大)
  • 【Game】Powerful——Hero Trial(11)
  • Windows下安装Docker Desktop到C盘以外的盘
  • 透视相机:创意摄影新体验,解锁照片无限可能
  • 计网第四次作业
  • MyBatis 一对多关联映射在Spring Boot中的XML配置
  • 北京市通州区经信局对新增通过国家级生成式人工智能及深度合成算法备案企业给予100w、20w一次性补贴
  • 【软考-软件设计师学习总结】- 计算机网络概述
  • MINIX 1.0 文件系统的实现(C/C++实现)
  • Lynx-字节跳动跨平台框架多端兼容Android, iOS, Web 原生渲染
  • Vue学习百日计划-Deepseek版
  • 残差网络(ResNet)
  • c/c++爬虫总结
  • docker使用过程中遇到概念问题
  • 线程的让位(Yield)
  • 修改linux同步时间
  • 潘大水库介绍
  • object的常用方法
  • MAC-OS X 命令行设置IP、掩码、网关、DNS服务器地址
  • 5月12日信息差