https://leetcode.com/problems/symmetric-tree/description/
判断一棵树是否对称
思路1:naive的方法。先层序遍历,检查每一层是否对称。此时还不能说明是对称(为什么?见下图)
这棵树层序遍历是“对称”的,但是实际上不对称的
所以还要加一次中序遍历,若中序的结果是轴对称的,则符合。
注意,若只中序遍历,即使结果轴对称,也不符合,如下图中序遍历:3,2,1,2,3:
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
import queue
class Solution:
def isSymmetric(self, root):
"""
:type root: TreeNode
:rtype: bool
"""
if not root:
return True
q = queue.Queue()
q.put(root)
flag = True #全局标志
#层序遍历
while not q.empty():
n = q.qsize() #层大小
data = []
for i in range(n):
node = q.get()
data.append(node.val) #记录该层数据
if node.left: #左子入栈
q.put(node.left)
if node.right: #右子入栈
q.put(node.right)
for i in range(n//2): #检测该层是否对称
if data[i] != data[n-1-i]:
flag = False
break
self.nums = [] #记录遍历结果
#中序遍历
self.inorder(root)
n = len(self.nums)
for i in range(n//2): #检测是否对称
if self.nums[i] != self.nums[n-1-i]:
flag = False
return flag
def inorder(self, root):
if root:
self.inorder(root.left)
self.nums.append(root.val)
self.inorder(root.right)
思路2:递归。
class Solution:
def isSymmetric(self, root):
"""
:type root: TreeNode
:rtype: bool
"""
return self.isMirror(root, root)
def isMirror(self, t1, t2): #比较结点t1和t2
if t1 == None and t2 == None: #若都为空
return True
elif t1 == None or t2 == None: #若上面不成立,说明不是都为空,即有一个为空,另一个不为空
return False
#否则都不为空
#比较t1和t2的值是否相等,且递归比较t1的左子和t2的右子,以及t1的右子和t2的左子
return t1.val == t2.val and self.isMirror(t1.left, t2.right) and self.isMirror(t1.right, t2.left)
思路3:还是层序。与思路1不同的是,分别对该树进行从左到右和从右到左的层序遍历,每次分别比较取出的结点,不相等则false
import queue
class Solution:
def isSymmetric(self, root):
"""
:type root: TreeNode
:rtype: bool
"""
q = queue.Queue()
q.put(root)
q.put(root)
#并不是严格的层序,每轮只取两个结点
#分别表示从左到右和从右到左的遍历顺序
while q.qsize() > 0:
t1 = q.get()
t2 = q.get()
if t1 == None and t2 == None:
continue
elif t1 == None or t2 == None:
return False
elif t1.val != t2.val:
return False
#t1的左右入队顺序无所谓,关键是t1要和t2对应上
#t1取左,t2对应就要取右,反之亦然
q.put(t1.left)
q.put(t2.right)
q.put(t1.right)
q.put(t2.left)
return True