力扣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. 迭代法(栈):深度优先,模拟递归过程。

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

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

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

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

相关推荐
monster000w3 小时前
大模型微调过程
人工智能·深度学习·算法·计算机视觉·信息与通信
小小晓.3 小时前
Pinely Round 4 (Div. 1 + Div. 2)
c++·算法
SHOJYS3 小时前
学习离线处理 [CSP-J 2022 山东] 部署
数据结构·c++·学习·算法
biter down3 小时前
c++:两种建堆方式的时间复杂度深度解析
算法
zhishidi3 小时前
推荐算法优缺点及通俗解读
算法·机器学习·推荐算法
WineMonk3 小时前
WPF 力导引算法实现图布局
算法·wpf
2401_837088503 小时前
双端队列(Deque)
算法
ada7_4 小时前
LeetCode(python)108.将有序数组转换为二叉搜索树
数据结构·python·算法·leetcode
奥特曼_ it4 小时前
【机器学习】python旅游数据分析可视化协同过滤算法推荐系统(完整系统源码+数据库+开发笔记+详细部署教程)✅
python·算法·机器学习·数据分析·django·毕业设计·旅游