请实现一个函数,用来判断一棵二叉树是不是对称的。如果一棵二叉树和它的镜像一样,那么它是对称的。
例如,二叉树 [1,2,2,3,4,4,3] 是对称的。
1
/ \
2 2
/ \ / \
3 4 4 3
但是下面这个 [1,2,2,null,3,null,3] 则不是镜像对称的:1
/ \
2 2
\ \
3 3
示例 1:
输入:root = [1,2,2,3,4,4,3]
输出:true
示例 2:输入:root = [1,2,2,null,3,null,3]
输出:false
先回忆之前的题目26:树的子结构
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
def isSubStructure(self, A: TreeNode, B: TreeNode) -> bool:
def isSubTree(A,B): # 判断A和B是否匹配
if not B:
return True
if not A:
return False
if A.val != B.val: # 根节点不同,A和B必然不匹配
return False
return isSubTree(A.left, B.left) and isSubTree(A.right, B.right)
if not B:
return False
if not A:
return False
# 判断匹配/ 遍历A的下一个子树来判断匹配
return isSubTree(A,B) or self.isSubStructure(A.left, B) or self.isSubStructure(A.right, B)
它的思路是:
如果B是A的子树,那么B的根节点显然是A中的某一个节点。因此,可以分为如下两步完成:
遍历树A的每一个节点n, 具体如下:
通过对A取左子树、右子树来不断迭代更新A的节点。
判断B是否是树A中以n为根节点的子树的子结构,具体如下:如果B为空,则B已经被匹配完,返回True;
如果B不为空且A为空,则不能成功匹配,返回False;
如果AB都不空但A和B的根节点不同, 那A和B也不可能匹配,返回False;
如果上面的情况都不是,那就继续判断A和B的左右子树是否分别相同。
上面这个题的思路在很多二叉树的题目中都有用,今天的题也不例外。可以按照下面的思路稍微改动一下上面的代码即可完成今日的题。
思路 递归
- 判断一棵树是否对称,只需要满足根节点的左右节点相同 且 每对对称节点(A,B)满足A的左节点恰好等于B的右节点即可。
- 之后,再以(A.left,B.right)和(B.right, A.left)为两对新的对称节点进行递归即可。
中止条件:
- A或B为空 或 二者根节点的值。若A和B同时为空,仍然对称,返沪Ture;
- 若A和B只有一个为空,不对称,返回False;
- 若A和B的根节点值不同,A和B不可能对称,返回False。
代码
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
def isSymmetric(self, root: TreeNode) -> bool:
def isSymTree(A,B): # 判断A和B是否匹配
if (not B) and (not A):
return True
if (not B) or (not A):
return False
if A.val != B.val: # 根节点不同,A和B必然不匹配
return False
return isSubTree(A.left, B.right) and isSubTree(A.right, B.left)
if not root:
return True
# 递归判断根节点
return isSymTree(root.right,root.left)
可以看到,和上面的代码是非常像的。
结果
总结
同一种数据结构的题之间的思路很多是相通的。