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

LeetCode-101:对称二叉树,镜像比较的关键是左左配右右

题目概述

给你一棵二叉树的根节点 root,判断这棵树是否轴对称——也就是说,它是不是自身的镜像。

举两个例子:

输入:[1,2,2,3,4,4,3]1/ \2   2/ \ / \3  4 4  3输出:True(左右完全镜像)
输入:[1,2,2,null,3,null,3]1/ \2   2\   \3   3输出:False(右边都挂在右孩子上,不是镜像)

核心思路:镜像 = 交叉比较

很多初学者第一反应是"左子树和右子树长得一样就行"。错! 对称不是相同,而是镜像

那镜像到底意味着什么?把一棵树沿中轴翻折之后,左右能完全重合。翻译成递归语言就是:

左子树的左孩子 要和 右子树的右孩子 相同;
左子树的右孩子 要和 右子树的左孩子 相同。

这就是"交叉比较"——外侧配外侧,内侧配内侧。

所以策略是:

  1. 写一个辅助函数 check(left, right),同时接收两个节点
  2. 两个都为空 → 对称,返回 True
  3. 只有一个为空,或者值不相等 → 不对称,返回 False
  4. 递归比较:check(left.left, right.right) check(left.right, right.left)

一句话记忆:"外侧比外侧,内侧比内侧"


代码实现

class Solution:def isSymmetric(self, root):def check(left, right):if not left and not right:return Trueif not left or not right:return Falseif left.val != right.val:return Falsereturn check(left.left, right.right) and check(left.right, right.left)return check(root.left, root.right)

逐行拆解

1. 入口:check(root.left, root.right)

从根节点出发,把左子树和右子树分别交给辅助函数做镜像比较。根节点本身不需要比——它是对称轴。

2. 终止条件一:if not left and not right: return True

两个指针都走到了空节点,说明这一路上结构和值都匹配,返回 True

3. 终止条件二:if not left or not right: return False

一个为空一个不为空,结构都不一样,直接返回 False

4. 值比较:if left.val != right.val: return False

结构一样(都不为空),但值不同,不是镜像。

5. 递归——交叉比较

return check(left.left, right.right) and check(left.right, right.left)

这是整道题的精髓:

  • check(left.left, right.right):外侧比外侧(左边的左孩子 vs 右边的右孩子)
  • check(left.right, right.left):内侧比内侧(左边的右孩子 vs 右边的左孩子)

两个方向都通过,才算对称。and 短路求值——只要外侧不通过,内侧就不用比了。


手动模拟

[1,2,2,3,4,4,3] 为例,画出完整树:

        1/ \2   2/ \ / \3  4 4  3

递归过程:

check(左2, 右2)值相同:2 == 2 ✓├── 外侧:check(左2的左孩子3, 右2的右孩子3)│     值相同:3 == 3 ✓│     ├── 外侧:check(None, None) → True ✓│     └── 内侧:check(None, None) → True ✓│     → True│└── 内侧:check(左2的右孩子4, 右2的左孩子4)值相同:4 == 4 ✓├── 外侧:check(None, None) → True ✓└── 内侧:check(None, None) → True ✓→ True最终:True and True → True ✓

再看反例 [1,2,2,null,3,null,3]

        1/ \2   2\   \3   3
check(左2, 右2)值相同:2 == 2 ✓├── 外侧:check(左2的左孩子None, 右2的右孩子3)│     一个为空一个不为空 → False ✗│└──(短路,内侧不再比较)最终:False

外侧交叉比较立刻发现了问题:左边没有左孩子,右边却有右孩子,结构不镜像。


复杂度分析

复杂度 说明
时间 O(n) 最坏情况下每个节点恰好被访问一次
空间 O(h) 递归栈深度等于树的高度 h;最坏情况(链状树)为 O(n),平衡树为 O(log n)

总结

要点 内容
核心思路 对称 = 镜像 = 交叉比较,外侧配外侧,内侧配内侧
递归函数 check(left, right) 同时传入两个节点
递归三要素 参数 = 一对镜像位置的节点,终止 = 都空或结构/值不匹配,返回 = 布尔值
易错点 对称不是"左右子树相同",而是"左右子树互为镜像"

这题是递归思维的经典入门题。它教会我们一个重要技巧:递归函数不一定只接收一个参数,当需要同时比较两个东西时,大胆地传两个参数进去。把"外侧比外侧、内侧比内侧"这个交叉比较模式记住,以后遇到镜像、回文相关的树题都能快速上手。

http://www.jsqmd.com/news/531133/

相关文章:

  • ESP32+Micropython实战:手把手教你用OLED ssd1306显示自定义中文(附字库工具)
  • 3步接入钉钉:OpenClaw+GLM-4.7-Flash打造智能工作台
  • LeetCode-543:二叉树的直径,求深度的同时顺手记录最长路径
  • 2026年比较好的医用钛棒源头工厂推荐 - 品牌宣传支持者
  • LeetCode-049:字母异位词分组,排序后长一样的字符串,本质上就是同一组
  • 美团APP竟删照片!客服称“第三方插件”冲突,有博主表示“华为工程师分析日志查到的”
  • 2026年Q3检测站第三方检测用熔体流动速率仪高精度与资质适配性深度评测报告:简支梁冲击试验机/落锤冲击试验机/选择指南 - 优质品牌商家
  • Qwen3.5-4B-Claude-Opus效果展示:JWT令牌签名验证与密钥轮换逻辑推演
  • 优化Ruffle扩展性能:从问题诊断到流畅体验的完整指南
  • 炼精化气:黄庭协议硬件升级的第一关,也是最关键的一关
  • SEO_从零开始,手把手教你制定SEO优化方案(366 )
  • 开箱即用!AnythingtoRealCharacters2511动漫转真人效果惊艳
  • 3个理由让开发者选择OpenCode:开源AI编程助手提升开发效率指南
  • 突破虚拟化限制:VMware macOS环境搭建全指南(开发者专业版)
  • 2026年知名的宝鸡钛棒/工业钛棒源头工厂推荐 - 品牌宣传支持者
  • 智能分割技术重塑三维建模:SAMPart3D如何提升效率与精准度
  • OpenClaw初学者指南:GLM-4.7-Flash模型入门10个问答
  • Qwen3-0.6B-FP8场景应用:快速搭建个人学习助手与创意写作工具
  • XUnity.AutoTranslator深度技术解析:游戏多语言翻译实战指南
  • 2026年热门的法兰头钛螺丝优质供应商推荐 - 品牌宣传支持者
  • 语音去混响技术突破:Nara WPE如何解决真实场景下的语音清晰度难题
  • 3步完成Traggo自托管部署:如何搭建个人时间跟踪系统
  • 误删Anaconda?3步快速恢复指南
  • 我的4GB内存小服务器跑Dify够用吗?实测CentOS7+Docker资源占用与优化指南
  • LeetCode-108:将有序数组转换为二叉搜索树,关键是每次取中间当根
  • 收藏家适用的和田玉专场拍卖优质推荐指南服务诚信权威:和田玉黄口、川料、新疆和田玉籽料、珠宝文玩、籽料碧玉、和田玉俄碧选择指南 - 优质品牌商家
  • REBANG 极简热榜:在信息洪流中,找回阅读的尊严
  • 从零开始:Anaconda环境下InternLM2-Chat-1.8B开发环境搭建
  • 最优化建模算法实践:Goldstein准则在MATLAB中的高效实现与性能对比
  • SEO_2024年最有效的SEO策略与最新趋势解读