力扣572. 另一棵树的子树(一入递归深似海)

题目:

给你两棵二叉树 root 和 subRoot 。检验 root 中是否包含和 subRoot 具有相同结构和节点值的子树。如果存在,返回 true ;否则,返回 false 。

二叉树 tree 的一棵子树包括 tree 的某个节点和这个节点的所有后代节点。tree 也可以看做它自身的一棵子树。

示例 1:

输入:root = [3,4,5,1,2], subRoot = [4,1,2]
输出:true

示例 2:

输入:root = [3,4,5,1,2,null,null,null,null,0], subRoot = [4,1,2]
输出:false

思路:

这道题虽说是简单难度但一点也不简单,递归不太好理解

要判断一个树 subRoot  是不是树 root的子树,那么可以判断 subRoot  是否和树 root的任意子树相等。那么就转化成 相同的树(力扣第100题)
即,这个题的做法就是在 root 的每个子节点上,判断该子节点是否和 subRoot  相等。

判断两个树是否相等的三个条件是与的关系,即:

  1. 当前两个树的根节点值相等;
  2. 并且,root 的左子树和 t 的左子树相等;
  3. 并且,root 的右子树和 t 的右子树相等。

而判断 subRoot  是否为 root 的子树的三个条件是或的关系,即:

  1. 当前两棵树相等;
  2. 或者,subRoot  是 root 的左子树;
  3. 或者,subRoot 是 root 的右子树。

代码及详细分析(and和or逻辑分析):

# 定义二叉树节点的类
# class TreeNode:
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right

class Solution:
    def isSubtree(self, root: Optional[TreeNode], subRoot: Optional[TreeNode]) -> bool:
        # 判断两棵树是否相同的方法
        def isSame(root, subRoot):
            # 如果两个节点都为空,则返回True
            if not root and not subRoot:
                return True
            # 如果其中一个节点为空,另一个不为空,则返回False
            elif not root or not subRoot:
                return False
            # 比较两个节点的值,并递归地比较它们的左右子树
            return root.val == subRoot.val and isSame(root.left, subRoot.left) and isSame(root.right, subRoot.right)

        # 如果根节点都为空,则返回True
        if not root and not subRoot:
            return True
        # 如果其中一个根节点为空,另一个不为空,则返回False
        elif not root or not subRoot:
            return False
        # 判断当前树是否和子树相同,或者左子树包含子树,或者右子树包含子树
        return isSame(root, subRoot) or self.isSubtree(root.left, subRoot) or self.isSubtree(root.right, subRoot)

当使用 and 运算符时,它会逐个计算表达式的值,如果所有表达式的值都为 True,整个表达式的值才为 True。如果有任何一个表达式的值为 False,整个表达式的值就为 False

在这个特定的代码行中,return root.val == subRoot.val and self.isSame(root.left, subRoot.left) and self.isSame(root.right, subRoot.right),它由三个部分组成,分别是:

  1. root.val == subRoot.val
  2. self.isSame(root.left, subRoot.left)
  3. self.isSame(root.right, subRoot.right)

这三个部分都是逻辑表达式,它们的值要么是 True,要么是 False

整个表达式的含义是:只有当 root 的值等于 subRoot 的值,并且 root 的左子树等于 subRoot 的左子树,并且 root 的右子树等于 subRoot 的右子树时,整个表达式的值才为 True,否则为 False

这里使用 and 运算符是为了确保三个条件都满足,才能判定两棵树是相同的。

 

当使用 or 运算符时,它会逐个计算表达式的值,如果其中有任何一个表达式的值为 True,整个表达式的值就为 True。只有当所有表达式的值都为 False,整个表达式的值才为 False

在这个特定的代码行中,return self.isSame(root, subRoot) or self.isSubtree(root.left, subRoot) or self.isSubtree(root.right, subRoot),它由三个部分组成,分别是:

  1. self.isSame(root, subRoot)
  2. self.isSubtree(root.left, subRoot)
  3. self.isSubtree(root.right, subRoot)

这三个部分都是逻辑表达式,它们的值要么是 True,要么是 False

整个表达式的含义是:只要其中有一个条件满足,整个表达式的值就为 True。具体来说,如果 root 和 subRoot 相同,或者 subRoot 是 root 的左子树的子树,或者 subRoot 是 root 的右子树的子树,整个表达式的值就为 True

这里使用 or 运算符是为了判断当前树是否和子树相同,或者左子树包含子树,或者右子树包含子树,只要有一个条件满足,就说明当前树包含子树。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

不染_是非

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

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

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

打赏作者

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

抵扣说明:

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

余额充值