给你一个二叉树的根节点 root , 检查它是否轴对称。
示例 1:
输入:root = [1,2,2,3,4,4,3]
输出:true
示例 2:
输入:root = [1,2,2,null,3,null,3]
输出:false
提示:
树中节点数目在范围 [1, 1000] 内
-100 <= Node.val <= 100
进阶:你可以运用递归和迭代两种方法解决这个问题吗?
解法:递归
乍一看无从下手,但用递归其实很好解决。
根据题目的描述,镜像对称,就是左右两边相等,也就是左子树和右子树是相当的。
注意这句话,左子树和右子树相等,也就是说要递归的比较左子树和右子树。
我们将根节点的左子树记做 left,右子树记做 right。比较 left 是否等于 right,不等的话直接返回就可以了。
如果相当,比较 left 的左节点和 right 的右节点,再比较 left 的右节点和 right 的左节点
比如看下面这两个子树(他们分别是根节点的左子树和右子树),能观察到这么一个规律:
左子树 22 的左孩子 == 右子树 22 的右孩子
左子树 22 的右孩子 == 右子树 22 的左孩子
2 2
/ \ / \
3 4 4 3
/ \ / \ / \ / \
8 7 6 5 5 6 7 8
根据上面信息可以总结出递归函数的两个条件:
终止条件:
- left 和 right 不等,或者 left 和 right 都为空
- 递归的比较 left,left 和 right.right,递归比较 left,right 和 right.left
动态图如下:
算法的时间复杂度是 O(n)O(n),因为要遍历 nn 个节点
空间复杂度是 O(n)O(n),空间复杂度是递归的深度,也就是跟树高度有关,最坏情况下树变成一个链表结构,高度是nn。
代码实现:
class Solution(object):
def isSymmetric(self, root):
"""
:type root: TreeNode
:rtype: bool
"""
if not root:
return True
def dfs(left,right):
# 递归的终止条件是两个节点都为空
# 或者两个节点中有一个为空
# 或者两个节点的值不相等
if not (left or right): # 两个节点都为空
return True
if not (left and right): # 两个节点中有一个为空
return False
if left.val!=right.val: # 两个节点的值不相等
return False
return dfs(left.left,right.right) and dfs(left.right,right.left)
# 调用递归函数,比较左节点,右节点
return dfs(root.left,root.right)