LeetCode刷题记录----101.对称二叉树(easy)

2025/8/4

题目(easy):


我的思路:

我一开始是想用递归的思路去解决,但是思考的过程中观察到如果这个树是轴对称的,那他的每一层的数字都相当于是一个回文数(比如题目第一个示例中第二层是22,第三层是3443),所以我就想到用层次遍历+回文数判断的方式来解决这个问题:

①声明一个队列并把头节点加入其中

②记录队列长度并把当前队列长度中元素弹出,并把当前弹出节点的左右孩子记录在一个数组中

③把记录数组进行头尾判断,如果头尾不相等则说明该层不为回文,也就是不为对称的

④如果通过了判断,就把数组中的元素加入到队列当中,并清空数组

⑤如果当前队列为空则说明所有层都判断完毕,否则继续重复二三四步骤进行判断

具体代码如下:

# 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
import queue

class Solution:
    def isSymmetric(self, root: Optional[TreeNode]) -> bool:
        #迭代:层次遍历
        if not root.left and not root.right:
            return True

        q = queue.Queue()
        q.put(root)

        while not q.empty():
            #记录当前的队列长度
            size = q.qsize()
            #用一个栈,存储长度前半部分出队的元素
            array = []
            for i in range(size):
                curNode = q.get()
                
                if curNode:
                    array.append(curNode.left)
                    array.append(curNode.right)


            #按回文比较这个队列
            for i in range(len(array)//2):
                frontNode = array[i]
                endNode = array[-i-1]
                if (frontNode and not endNode) or (not frontNode and endNode):
                    return False
                elif frontNode and endNode and frontNode.val != endNode.val:
                    return False

            #比较完能到这里,那就继续装填进队列
            for node in array:
                q.put(node)
            array.clear()

        #如果能顺利出来就说明是true
        return True

时间复杂度:O(N)

空间复杂度:O(N)


优化思路:

1.更好地利用队列空间的迭代

在我的思路中,我用到了一个额外的列表变量来存储下一层的节点,并在这里进行该层的对称性判断。

之前把下一层加入数组中的形式(以最后一层示例)

但是我们其实可以不需要用额外的列表空间来帮助我们实现这个步骤,我们只需要在把当前层的节点加入队列的时候做一些小细节处理,就可以做到队列中每次取出两个相邻的节点就为需要进行对称判断的节点。

现在我们打算把下一层加入队列中的顺序

大致步骤是:

①声明队列,并把根节点加进去两次

②获取队列长度,并以步长为2,每次弹出队列中两个元素进行比较处理(比较发现不对称就返回false了)

③比较完毕后,把两个元素的左右孩子按左元素左孩子、右元素右孩子、左元素右孩子、右元素左孩子的顺序加入到队列当中去

④判断当前队列是否为空,不为空则继续重复步骤二三

具体代码如下:

# 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

import queue

class Solution:
    def isSymmetric(self, root: Optional[TreeNode]) -> bool:
       #迭代
        return self.check(root.left, root.right)
    
    #检查左右子树是否对称
    def check(self, left: Optional[TreeNode], right: Optional[TreeNode]) -> bool:
        #定义队列并把传入的两个节点加入队列当中
        q = queue.Queue()
        q.put(left)
        q.put(right)

        while not q.empty():
            size = q.qsize()
            for _ in range(0, size, 2):
                #每次得到两个节点
                node1 = q.get()
                node2 = q.get()
                
                #判断这两个节点是否存在,以及相等
                if not node1 and not node2:
                    continue
                elif (not node1 or not node2) or (node1.val != node2.val):
                    return False


                #判断完了,有顺序地把下一层的节点加入队列中
                q.put(node1.left)
                q.put(node2.right)
                q.put(node1.right)
                q.put(node2.left)
        
        return True

时间复杂度:O(N)

空间复杂度:O(N)【相比之前的步骤还是节约了一点额外数组的开销的】

2.递归处理

当然,对于这种树,递归的思路肯定是少不了的。那我们就必须考虑递归的输入和输出。观察这个树轴对称的条件发现有:左右子树是镜像对称的(①左右子树的根节点相同②左右子树的左右子树镜像对称)。由以上的观察我们可以把问题转化为判断两颗树是否镜像对称。所以我们决定了:输入是两个树的根节点,输出是两个树是否镜像对称。大致步骤是:

①传入当前树的左右子树的根节点

②在递归条件下判断左右子树根节点的对称性

③返回左右子树是否满足镜像对称条件(根节点相同,左右子树的左右子树镜像对称)

具体代码如下:

# 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:
       #递归
        return self.check(root.left, root.right)
    
    #检查左右子树是否对称
    def check(self, left: Optional[TreeNode], right: Optional[TreeNode]) -> bool:
        #先检查根节点的值是否相同
        if not left and not right:
            return True
        elif not left or not right:
            return False

        #然后检查这两颗树是否满足对称的条件(根节点值相同,左边树的右子树和右边树的左子树镜像,)
        return left.val == right.val and self.check(left.right, right.left) and self.check(left.left, right.right)

        

时间复杂度:O(N)

空间复杂度:O(N)


总结:

①对于树的对称性,需要观察他的特征特点,然后才能够想到对应的解决思路。(层次回文,队列规律放置顺序,两颗树的对称关系以递归)。善于把左右子树也都当成独立的树去考虑。

②有些边界条件比较简单的最好在一开始就判断清楚,不要把他带到后面的逻辑处理当中。比如这里左右节点是否为空,都为空则一定对称不用比较值也不用加入值(不参与后续的逻辑处理),有一个为空则一定不对称,那直接整个返回False(直接终止程序了)

③合理地利用好队列的顺序也可以帮助我们记录更多的信息以解决问题

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

萘柰奈

谢谢老板喵

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值