每日一道 LeetCode (21):对称二叉树
每天 3 分钟,走上算法的逆袭之路。
前文合集
代码仓库
GitHub: https://github.com/meteor1993/LeetCode
Gitee: https://gitee.com/inwsy/LeetCode
题目:对称二叉树
题目来源:https://leetcode-cn.com/problems/symmetric-tree/
给定一个二叉树,检查它是否是镜像对称的。
例如,二叉树 [1,2,2,3,4,4,3] 是对称的。
1
/ \
2 2
/ \ / \
3 4 4 3
但是下面这个 [1,2,2,null,3,null,3] 则不是镜像对称的:
1
/ \
2 2
\ \
3 3
进阶:
你可以运用递归和迭代两种方法解决这个问题吗?
解题思路
LeetCode 题的顺序蛮有意思的么,还按照数据结构来,先是数组,然后是列表,接着是链表,现在轮到的二叉树,已经连续两天是二叉树了,这是怕我们一道题学不会还带强化练习一下的么。。。
今天这道题和昨天那道题从解法上来讲有点像,都是两种方案,递归和迭代,看来处理二叉树的问题,一般都会使用到这两种手段。
至于这道题的解法,emmmmmmmmmmmmmmmm......
原谅我做题少,直接翻开了参考答案。
这道题的核心在于,如何判断一个二叉树是对称二叉树?
我看到官方解法把这个问题转化了一下,转化成下面这样:
嗯,没问题,确实是这样的,竟然如此简单。
可我为啥就是想不到呢?
菜就是做题少,多做点题就知道了。
解题方案一:递归
递归的思路很简单,同步的移动两个指针,一个向左移动,另一个向右移动,比较这两个指针指向的元素是否相等。
public boolean isSymmetric(TreeNode root) {
return check(root, root);
}
public boolean check(TreeNode p, TreeNode q) {
if (p == null && q == null) return true;
if (p == null || q == null) return false;
return p.val == q.val && check(p.left, q.right) && check(p.right, q.left);
}
解题方案二:迭代
昨天的那道题,我们使用了两个队列,分别来存放两个二叉树进行比较,今天这道题一样可以使用两个队列进行操作,只是需要一个队列先放入左子树,另一个队列先放入右子树。
public boolean check_2(TreeNode p, TreeNode q) {
Queue<TreeNode> queue1 = new LinkedList<>();
Queue<TreeNode> queue2 = new LinkedList<>();
queue1.offer(p);
queue2.offer(q);
while (!queue1.isEmpty() && !queue2.isEmpty()) {
TreeNode node1 = queue1.poll();
TreeNode node2 = queue2.poll();
if (node1 == null && node2 == null) continue;
if ((node1 == null || node2 == null) || (node1.val != node2.val)) return false;
queue1.offer(node1.left);
queue1.offer(node1.right);
queue2.offer(node2.right);
queue2.offer(node2.left);
}
return true;
}
这个方案稍有不足,就是我们使用了两个队列,实际上在答案中给出的方案是使用一个队列就可以完成的。
初始化时我们把根节点入队两次。每次提取两个结点并比较它们的值(队列中每两个连续的结点应该是相等的,而且它们的子树互为镜像),然后将两个结点的左右子结点按相反的顺序插入队列中。
public boolean check_1(TreeNode p, TreeNode q) {
Queue<TreeNode> queue = new LinkedList<>();
queue.offer(p);
queue.offer(q);
while (!queue.isEmpty()) {
p = queue.poll();
q = queue.poll();
if (p == null && q == null) continue;
if ((p == null || q == null) || (p.val != q.val)) return false;
queue.offer(p.left);
queue.offer(q.right);
queue.offer(p.right);
queue.offer(q.left);
}
return true;
}
这两种方案,耗时都是一致的,时间复杂度都是 O(n) 。
作者:极客挖掘机
定期发表作者的思考:技术、产品、运营、自我提升等。
本文版权归作者极客挖掘机和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
如果您觉得作者的文章对您有帮助,就来作者个人小站逛逛吧:极客挖掘机
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· DeepSeek如何颠覆传统软件测试?测试工程师会被淘汰吗?