【LeetCode刷题】对称二叉树

给你一个二叉树的根节点 root , 检查它是否轴对称。

示例 1:

复制代码
输入:root = [1,2,2,3,4,4,3]
输出:true

示例 2:

复制代码
输入:root = [1,2,2,null,3,null,3]
输出:false

提示:

  • 树中节点数目在范围 [1, 1000]
  • -100 <= Node.val <= 100

解题思路

判断二叉树是否轴对称的核心是判断左右子树是否镜像对称,满足以下条件:

  1. 节点值相等:左右两个对应节点的值必须相同;
  2. 子树镜像:左节点的左子树与右节点的右子树镜像,左节点的右子树与右节点的左子树镜像。
递归思路
  • 用辅助函数_is_mirror比较两个子树:
    • 边界:两个节点都为空则对称;一个为空、一个不为空则不对称;
    • 递归:值相等时,继续比较左的左与右的右、左的右与右的左。

Python代码

python 复制代码
from typing import Optional, List, Deque
from collections import deque


# 二叉树节点定义
class TreeNode:
    def __init__(self, val=0, left=None, right=None):
        self.val = val
        self.left = left
        self.right = right


class Solution:
    def isSymmetric(self, root: Optional[TreeNode]) -> bool:
        # 空树直接对称
        if not root:
            return True
        # 递归判断左右子树是否镜像对称
        return self._is_mirror(root.left, root.right)

    def _is_mirror(self, left: Optional[TreeNode], right: Optional[TreeNode]) -> bool:
        """辅助函数:判断两个子树是否镜像对称"""
        # 两个节点都为空 → 对称
        if not left and not right:
            return True
        # 一个为空、一个不为空 → 不对称
        if not left or not right:
            return False
        # 节点值相等,且左的左与右的右镜像、左的右与右的左镜像 → 对称
        return (left.val == right.val) and \
            self._is_mirror(left.left, right.right) and \
            self._is_mirror(left.right, right.left)


# ---------------------- 测试辅助函数 ----------------------
def build_tree(nums: List[Optional[int]]) -> Optional[TreeNode]:
    """
    层序遍历构建二叉树(完全适配LeetCode的二叉树数组表示法)
    :param nums: 数组,None表示空节点,如[1,2,2,3,4,4,3]、[1,2,2,None,3,None,3]
    :return: 构建好的二叉树根节点
    """
    if not nums or nums[0] is None:
        return None
    root = TreeNode(nums[0])
    queue: Deque[TreeNode] = deque([root])
    idx = 1  # 从第二个元素开始遍历
    while queue and idx < len(nums):
        cur_node = queue.popleft()
        # 构建左子节点
        if nums[idx] is not None:
            cur_node.left = TreeNode(nums[idx])
            queue.append(cur_node.left)
        idx += 1
        # 构建右子节点(注意边界,防止数组越界)
        if idx < len(nums) and nums[idx] is not None:
            cur_node.right = TreeNode(nums[idx])
            queue.append(cur_node.right)
        idx += 1
    return root


def print_tree(root: Optional[TreeNode]) -> List[Optional[int]]:
    """
    层序遍历打印二叉树(转回数组,方便直观查看树结构)
    :param root: 二叉树根节点
    :return: 层序遍历的数组,末尾无多余None
    """
    if not root:
        return []
    res = []
    queue: Deque[TreeNode] = deque([root])
    while queue:
        cur_node = queue.popleft()
        if cur_node:
            res.append(cur_node.val)
            queue.append(cur_node.left)
            queue.append(cur_node.right)
        else:
            res.append(None)
    # 移除末尾的空节点,让结果更整洁
    while res and res[-1] is None:
        res.pop()
    return res


# ---------------------- 测试用例 ----------------------
if __name__ == "__main__":
    # 初始化解法对象
    sol = Solution()

    # 测试用例1:对称二叉树(LeetCode示例1)
    nums1 = [1, 2, 2, 3, 4, 4, 3]
    root1 = build_tree(nums1)
    print(f"测试用例1 - 原树结构:{print_tree(root1)}")
    print(f"测试用例1 - 是否对称:{sol.isSymmetric(root1)}")  # 预期True

    # 测试用例2:非对称二叉树(LeetCode示例2)
    nums2 = [1, 2, 2, None, 3, None, 3]
    root2 = build_tree(nums2)
    print(f"\n测试用例2 - 原树结构:{print_tree(root2)}")
    print(f"测试用例2 - 是否对称:{sol.isSymmetric(root2)}")  # 预期False

    # 测试用例3:空树(边界情况)
    nums3 = []
    root3 = build_tree(nums3)
    print(f"\n测试用例3 - 原树结构:{print_tree(root3)}")
    print(f"测试用例3 - 是否对称:{sol.isSymmetric(root3)}")  # 预期True

    # 测试用例4:只有根节点的树(边界情况)
    nums4 = [5]
    root4 = build_tree(nums4)
    print(f"\n测试用例4 - 原树结构:{print_tree(root4)}")
    print(f"测试用例4 - 是否对称:{sol.isSymmetric(root4)}")  # 预期True

    # 测试用例5:两层对称二叉树
    nums5 = [10, 6, 6]
    root5 = build_tree(nums5)
    print(f"\n测试用例5 - 原树结构:{print_tree(root5)}")
    print(f"测试用例5 - 是否对称:{sol.isSymmetric(root5)}")  # 预期True

LeetCode提交代码

python 复制代码
# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution:
    def isSymmetric(self, root: Optional[TreeNode]) -> bool:
        # 空树直接对称
        if not root:
            return True
        # 递归判断左右子树是否镜像对称
        return self._is_mirror(root.left, root.right)
    
    def _is_mirror(self, left: Optional[TreeNode], right: Optional[TreeNode]) -> bool:
        """辅助函数:判断两个子树是否镜像对称"""
        # 两个节点都为空 → 对称
        if not left and not right:
            return True
        # 一个为空、一个不为空 → 不对称
        if not left or not right:
            return False
        # 节点值相等,且左的左与右的右镜像、左的右与右的左镜像 → 对称
        return (left.val == right.val) and \
               self._is_mirror(left.left, right.right) and \
               self._is_mirror(left.right, right.left)

程序运行结果展示

bash 复制代码
测试用例1 - 原树结构:[1, 2, 2, 3, 4, 4, 3]
测试用例1 - 是否对称:True

测试用例2 - 原树结构:[1, 2, 2, None, 3, None, 3]
测试用例2 - 是否对称:False

测试用例3 - 原树结构:[]
测试用例3 - 是否对称:True

测试用例4 - 原树结构:[5]
测试用例4 - 是否对称:True

测试用例5 - 原树结构:[10, 6, 6]
测试用例5 - 是否对称:True

总结

本文探讨如何判断二叉树是否轴对称。核心思路是递归比较左右子树是否镜像对称:对应节点值必须相等,且左节点的左子树与右节点的右子树、左节点的右子树与右节点的左子树均需对称。Python实现通过辅助函数_is_mirror递归验证这些条件,并处理边界情况(如空树或单节点树)。测试用例验证了对称树(如[1,2,2,3,4,4,3])和非对称树(如[1,2,2,None,3,None,3])的正确性,最终提交代码符合LeetCode要求。

相关推荐
飞机和胖和黄2 小时前
王道考研C语言第五周
c语言·考研·算法
小饼干超人2 小时前
pytorch返回张量元素总数量的方法 x.numel()
人工智能·pytorch·python
张3蜂2 小时前
java springboot2.0 api ;.netcore8 api ;python GunicornAPI ,哪种更强?请从多个维度,对比分析
java·python·.netcore
u0109272712 小时前
高级爬虫技巧:处理JavaScript渲染(Selenium)
jvm·数据库·python
七夜zippoe2 小时前
Plotly + Dash:构建交互式数据仪表盘的艺术与实战
python·信息可视化·架构·dash·回到函数
市场部需要一个软件开发岗位2 小时前
一个无人机平台+算法监督平台的离线部署指南
java·python·算法·bash·无人机·持续部署
ygklwyf2 小时前
零基础薄纱树套树——高级数据结构的结合
算法·线段树·树状数组·树套树
喵手2 小时前
Python爬虫实战:房产数据采集实战 - 链家二手房&安居客租房多页爬虫完整方案(附CSV导出 + SQLite持久化存储)!
爬虫·python·爬虫实战·零基础python爬虫教学·房产数据采集·链家二手房/安居客房源采集·采集结果sqlite导出
不懒不懒2 小时前
【机器学习:下采样 VS 过采样——逻辑回归在信用卡欺诈检测中的实践】
python·numpy·scikit-learn·matplotlib·pip·futurewarning