【Leetcode】101. Symmetric Tree

https://leetcode-cn.com/problems/symmetric-tree/

1. 描述

Given the root of a binary tree, check whether it is a mirror of itself (i.e., symmetric around its center).

在这里插入图片描述

2. 解决

2.1 递归——DFS(深度优先)

递归思想:

  • 左孩子的左孩子 = 右孩子的右孩子 (e.g.:1.left.left == 1.right.right)
  • 左孩子的右孩子 = 右孩子的左孩子 (e.g.:1.left.right == 1.right.left)

递归出口:

  • 左右结构不同(比如:左孩子存在但右孩子不存在)
  • 递归思想中的等式不成立

时间复杂度: O(n),因为要遍历 n 个节点。
空间复杂度: O(n),空间复杂度是递归的深度,也就是跟树高度有关,最坏情况下树变成一个链表结构,高度是n。

# Definition for a binary tree node.
# class TreeNode(object):
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution(object):
    def isSymmetric(self, root):
        """
        :type root: TreeNode
        :rtype: bool
        """
        if not root:  # 无根,直接True
            return True
        
        def dfs(left, right):  # 递归函数
            if not (left or right):  # 左右孩子都不存在,即只有根节点→ True
                return True
            if not (left and right):  # 左右结构不同→ False
                return False
            if left.val != right.val:  # 左右结构相同但值不同→ False
                return False
            # 开始递归比较“左孩子的左孩子” 与 “右孩子的右孩子”,“左孩子的右孩子” 与 “右孩子的左孩子”
            return dfs(left.left, right.right) and dfs(left.right, right.left)
        
        # 调用递归函数
        return dfs(root.left, root.right)    

2.2 迭代——BFS(广度优先)

思想还是:

  • 左孩子的左孩子 = 右孩子的右孩子 (e.g.:1.left.left == 1.right.right)
  • 左孩子的右孩子 = 右孩子的左孩子 (e.g.:1.left.right == 1.right.left)

只不过不通过递归来表示,可以使用队列

  1. 将根节点的两个孩子放入队列
  2. 每次 pop 出两个节点,并进行比较:(注意pop()弹出的是最后一个,pop(0)弹出的是第一个)
    1. 都为空→ 跳出本次循环continue
    2. 一个空一个非空→ False
    3. 都非空,但值不同→ False
    4. 都非空,且值相同→ 更新队列
  3. 更新队列:将下一层依次加入队列(跟递归思想一致):
    1. 左孩子的左孩子
    2. 右孩子的右孩子
    3. 左孩子的右孩子
    4. 右孩子的左孩子

时间复杂度: O(n)。
空间复杂度: O(n)。

# Definition for a binary tree node.
# class TreeNode(object):
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution(object):
    def isSymmetric(self, root):
        """
        :type root: TreeNode
        :rtype: bool
        """
        # 无根 or 根无孩子→ True
        if not root or not (root.left or root.right):
            return True

        # 将根节点的两个孩子放入队列
        queue = [root.left, root.right]
        while queue:
            # 每次 pop 两个节点进行比较
            left = queue.pop(0)
            right = queue.pop(0)

            # 无孩子→ 跳出本次循环continue
            if not (left or right):
                continue
                
            # 结构不同→ False
            if not (left and right):
                return False
            
            # 结构同,值不同→ False
            if left.val != right.val:
                return False
            
            # 将左节点的左孩子, 右节点的右孩子放入队列
            queue.append(left.left)
            queue.append(right.right)
            
            # 将左节点的右孩子,右节点的左孩子放入队列
            queue.append(left.right)
            queue.append(right.left)
        return True
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值