Leetcode Link: 101. 对称二叉树 - 力扣(LeetCode) (leetcode-cn.com) 剑指 Offer 28. 对称的二叉树 - 力扣(LeetCode)

题目

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

解法一

思路: 利用层次遍历的思路,将每一层的节点送到curLevel列表中,然后判断当前层是不是对称的 区别:要将None节点的值也保存在curLevel中 难点:如何判断当前层是不是对称的(提示:第0层,奇数个节点,列表逆序)

题解:这是我自己想的一个解法,还没看到别人用同样的解法

class Solution:
    def isSymmetric(self, root: Optional[TreeNode]) -> bool:
        if not root:
            return True
        q1 = collections.deque() # 当前层队列
        q2 = collections.deque() # 下一层队列
        q1.append(root)
        while(1):
            curLevel = []
            while(q1):
                cur = q1.popleft()
                if not cur:
                    curLevel.append(None)
                else:
	                # 开始的时候把这句忘了
                    curLevel.append(cur.val)
                    q2.append(cur.left)
                    q2.append(cur.right)
            # 初始提交的时候没注意根节点时curLevel为1的情况
            # 不是第0层的时候,只要节点数是奇数,一定不对称
            if (len(curLevel) % 2 != 0 and len(curLevel) != 1) or (curLevel != curLevel[::-1]):
                return False
            # q2 为空说明下一层的节点为空,即到底了
            if not q2:
                break
            else:
                q1, q2 = q2, q1
        
        return True

解法二

思路:递归。该问题可以转化为:两个树在什么情况下互为镜像?如果同时满足下面的条件,两个树互为镜像(要从根节点开始才成立):

  • 它们的两个根结点具有相同的值
  • 每个树的右子树都与另一个树的左子树镜像对称

对于递归的终止条件:

  • 当两个节点都为空,进入下一循环;
  • 左右两个节点一个为空,一个不为空,一定不对称返回False;
  • 左右两个节点都不为空,值不相等,一定不对称返回False.

题解

class Solution:
    def isSymmetric(self, root: Optional[TreeNode]) -> bool:
        if not root:
            return True
        return self.check(root.left, root.right)
 
    def check(self, left, right):
        # 俩都是None,是对称的
        if left==None and right==None:
            return True
        # 俩type不同,又都不是None,那肯定不对称
        if type(left) != type(right):
            return False
        # 值不等,不对称
        if left.val != right.val:
            return False
        
        return self.check(left.left, right.right) and \
		       self.check(left.right, right.left)

解法三

思路:迭代(递归改迭代)。回想下递归的实现: 当两个子树的根节点相等时,就比较: 左子树的 left 和 右子树的 right,这个比较是用递归实现的。 现在我们改用队列来实现,思路如下: 首先从队列中拿出两个节点(left 和 right)比较 将 left 的 left 节点和 right 的 right 节点放入队列 将 left 的 right 节点和 right 的 left 节点放入队列 时间复杂度是 O(n),空间复杂度是 O(n)

题解

class Solution:
    def isSymmetric(self, root: Optional[TreeNode]) -> bool:
        if not root:
            return True
        q = collections.deque()
        # root 要先放进去两次,要不然取不出来第一次的left和right
        q.append(root)
        q.append(root)
 
        while(q):
            left = q.popleft()
            right = q.popleft()
            # 值不等,不对称
            if left.val != right.val:
                return False
            # 类型不同,不对称                
            if (type(left.left)!=type(right.right)) or \ 
               (type(left.right)!=type(right.left)):
                return False
            # 都不为None,对称送入队列
            if left.left and right.right:
                q.append(left.left)
                q.append(right.right)
            if left.right and right.left:
                q.append(left.right)
                q.append(right.left)
        return True

启发和联系

解法二三我开始理解了好久,因为只有从根节点开始才行。