力扣101.判断对称二叉树-推荐掌握递归

题目描述

给定一个二叉树的根节点 root,检查它是否轴对称(镜像对称)。

示例1:

复制代码
    1
   / \
  2   2
 / \ / \
3  4 4  3

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

输出:true

示例2:

复制代码
    1
   / \
  2   2
   \   \
   3    3

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

输出:false

问题理解

判断二叉树是否轴对称,意味着我们需要检查这棵树是否是自身的镜像。换句话说,对于树中的每个节点:

  • 左子树和右子树的结构必须对称

  • 对应位置的节点值必须相等

核心思路

思路一:递归法(深度优先搜索)

递归是最直观的解法。对于两棵树是否对称,我们可以定义递归规则:

python 复制代码
class Solution:
    def isSymmetric(self, root: Optional[TreeNode]) -> bool:
        def recur(left:TreeNode,right:TreeNode)->bool:
            if not left and not right:#左右都空
                return True
            if not left or not right or left.val!=right.val:#有一个为空或值不相等
                return False
            return recur(left.left,right.right) and recur(left.right,right.left)
        return recur(root.left,root.right) or not root #考虑根为空

递归终止条件:

  1. 两个节点都为空 → 对称

  2. 一个为空一个不为空 → 不对称

  3. 两个节点值不相等 → 不对称

递归过程:

比较左子树的左节点与右子树的右节点,以及左子树的右节点与右子树的左节点。

思路二:迭代法(广度优先搜索)

递归可能会因为树深度过大导致栈溢出,因此我们可以使用迭代法。迭代法通常使用队列或栈来实现:

使用队列(BFS风格)
python 复制代码
from collections import deque

def is_symmetric_iterative(root):
    if not root:
        return True
    
    queue = deque()
    queue.append((root.left, root.right))
    
    while queue:
        left, right = queue.popleft()
        
        if not left and not right:
            continue
        if not left or not right or left.val != right.val:
            return False
        
        queue.append((left.left, right.right))
        queue.append((left.right, right.left))
    
    return True
使用栈(DFS风格)
python 复制代码
def is_symmetric_stack(root):
    if not root:
        return True
    
    stack = [(root.left, root.right)]
    
    while stack:
        left, right = stack.pop()
        
        if not left and not right:
            continue
        if not left or not right or left.val != right.val:
            return False
        
        stack.append((left.left, right.right))
        stack.append((left.right, right.left))
    
    return True

算法分析

时间复杂度

  • 所有方法的时间复杂度都是 O(n),其中 n 是树中节点的数量。每个节点最多被访问一次。

空间复杂度

  1. 递归法:O(h),其中 h 是树的高度。空间消耗来自递归调用栈。

  2. 迭代法(队列/栈):O(n),在最坏情况下(完全二叉树),队列/栈中需要存储大约 n/2 个节点。

方法对比

方法 优点 缺点 适用场景
递归法 代码简洁,逻辑清晰 可能栈溢出(树很深时) 树深度不大时
迭代法(队列) 不会栈溢出,适合深树 代码稍复杂,需要额外空间 树深度很大时
迭代法(栈) 模拟递归过程,直观 同队列法,需要额外空间 树深度很大时

常见误区

  1. 只比较值不比较结构:对称性不仅要求值相等,还要求结构对称。例如,左子树的左节点必须与右子树的右节点对应。

  2. 忽略空节点:空节点也需要参与比较。两个空节点是对称的,但一个空一个不空就是不对称的。

  3. 只检查直接子节点:需要递归检查整个子树,而不仅仅是直接子节点。

扩展思考

如何判断两棵树是否相同?

将对称判断的代码稍作修改即可:

python 复制代码
def is_same_tree(p, q):
    if not p and not q:
        return True
    if not p or not q or p.val != q.val:
        return False
    return is_same_tree(p.left, q.left) and is_same_tree(p.right, q.right)

如何获取树的镜像?

通过递归交换左右子树:

python 复制代码
def mirror_tree(root):
    if not root:
        return None
    
    # 交换左右子树
    root.left, root.right = root.right, root.left
    
    # 递归处理子树
    mirror_tree(root.left)
    mirror_tree(root.right)
    
    return root

总结

判断二叉树是否对称是一个经典的二叉树问题,考察了对二叉树遍历和递归的理解。本文介绍了三种解法:

  1. 递归法:最直观,代码简洁,适合面试快速实现。

  2. 迭代法(队列):广度优先,适合树深度较大的情况。

  3. 迭代法(栈):深度优先,模拟递归过程。

在实际应用中,可以根据具体情况选择合适的方法:

  • 对于一般情况,递归法足够使用。

  • 对于深度可能很大的树,建议使用迭代法避免栈溢出。

掌握这个问题的解法,不仅有助于解决类似二叉树问题,还能加深对递归、树遍历等核心算法思想的理解。

相关推荐
努力学算法的蒟蒻12 小时前
day61(1.20)——leetcode面试经典150
面试·职场和发展
夏鹏今天学习了吗12 小时前
【LeetCode热题100(87/100)】最小路径和
算法·leetcode·职场和发展
哈哈不让取名字12 小时前
基于C++的爬虫框架
开发语言·c++·算法
Lips61114 小时前
2026.1.20力扣刷题笔记
笔记·算法·leetcode
2501_9413297214 小时前
YOLOv8-LADH马匹检测识别算法详解与实现
算法·yolo·目标跟踪
洛生&14 小时前
Planets Queries II(倍增,基环内向森林)
算法
小郭团队15 小时前
1_6_五段式SVPWM (传统算法反正切+DPWM2)算法理论与 MATLAB 实现详解
嵌入式硬件·算法·matlab·dsp开发
小郭团队15 小时前
1_7_五段式SVPWM (传统算法反正切+DPWM3)算法理论与 MATLAB 实现详解
开发语言·嵌入式硬件·算法·matlab·dsp开发
鱼跃鹰飞15 小时前
Leetcode347:前K个高频元素
数据结构·算法·leetcode·面试
bybitq15 小时前
LeetCode236-二叉树的最近公共祖先(LCA)问题详解-C++
算法·深度优先