LeetCode572. Subtree of Another Tree (另一个棵树的子树)

原题

Given two non-empty binary trees s and t, check whether tree t has exactly the same structure and node values with a subtree of s. A subtree of s is a tree consists of a node in s and all of this node’s descendants. The tree s could also be considered as a subtree of itself.

Example 1:
Given tree s:

     3
    / \
   4   5
  / \
 1   2

Given tree t:

   4 
  / \
 1   2

Return true, because t has the same structure and node values with a subtree of s.

Example 2:
Given tree s:

     3
    / \
   4   5
  / \
 1   2
    /
   0

Given tree t:

   4
  / \
 1   2

Return false.

Reference Answer

Method one: DFS + DFS

容易想到,要判断一个树是不是另外一个树的子树,那么可以通过判断和这个数的任意子树是否相等的方式来做。那么就和100. Same Tree挺像了。所以这个题的做法就是在判断两棵树是否相等的基础上,添加上任意子树是否相等的判断。

任意子树是否相等判断的方式是:

  1. 当前两棵树是否相等
  2. s的左孩子和t是否相等
  3. t的左孩子和t是否相等

这三个条件是 的关系。
注意,判断两个数是否相等是与的关系。
判断是否是子树与是否是相同的树的代码简直是对称美啊~

这里很值得注意的一个地方时,无论是方法一还是方法二,都用了如下代码先从树结构进行判定:

if not s and not t:
    return True
if not s or not t:
    return False

其依据是“在当节点为空的时候给一个“#”表示,这样就能表示出不同的子树,因此只需要遍历一次就能得到结果。每次遍历到树的结尾的时候能够按照#区分,另外每个树的节点值之间用","分割。”

Code

class Solution:
    def isSubtree(self, s, t):
        """
        :type s: TreeNode
        :type t: TreeNode
        :rtype: bool
        """
# 1. method one: DFS + DFS

        if not s and not t:
            return True
        if not s or not t:
            return False
        return self.isSameTree(s,t) or self.isSubtree(s.left, t) or self.isSubtree(s.right, t)
    
    
    def isSameTree(self, s, t):
        if not s and not t:
            return True
        if not s or not t:
            return False
        return s.val == t.val and self.isSameTree(s.left, t.left) and self.isSameTree(s.right, t.right)
            

Method Two: BFS + DFS

因为s的每个节点都可能成为和t相等的根节点,那么我们使用BFS来遍历每个节点,然后对每个节点进行判断就好了。

参考答案采用了colletions.deque()暂存节点,这种方式比采用list更巧妙,先进先出也完全符合程序设定。

class Solution:
    def isSubtree(self, s, t):
        """
        :type s: TreeNode
        :type t: TreeNode
        :rtype: bool
        """  
# 2. method two: BFS + DFS
        if not s and not t:
            return True
        if not s or not t:
            return False
        que = collections.deque()
        que.append(s)
        while que:
            node = que.popleft()
            if not node:
                continue
            if self.isSameTree(node, t):
                return True
            que.append(node.left)
            que.append(node.right)
        return False
            

    def isSameTree(self, s, t):
        if not s and not t:
            return True
        if not s or not t:
            return False
        return s.val == t.val and self.isSameTree(s.left, t.left) and self.isSameTree(s.right, t.right)        

Note

  • 自己尝试着用后续遍历进行判定,存储两棵树节点值,进行判定的依据是认为是子树结构必然存储在后续遍历开始,没通过的原因正是在于该依据有错误,当树结构比较深时,其子结构可能存在中间,这时候子树结构无法对应原树结构的开始节点位置。

参考文献

[1] https://blog.csdn.net/fuxuemingzhu/article/details/71440802

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值