面试题28 对称的二叉树 Python3 递归

请实现一个函数,用来判断一棵二叉树是不是对称的。如果一棵二叉树和它的镜像一样,那么它是对称的。

例如,二叉树 [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)

可以看到,和上面的代码是非常像的。

 

结果

 

总结

同一种数据结构的题之间的思路很多是相通的。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

R.X. NLOS

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值