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启发和联系
解法二三我开始理解了好久,因为只有从根节点开始才行。