【Leetcode】100. Same Tree

https://leetcode-cn.com/problems/same-tree/

1. 描述

Given the roots of two binary trees p and q, write a function to check if they are the same or not.

Two binary trees are considered the same if they are structurally identical, and the nodes have the same value.
在这里插入图片描述

2. 解决

总体思想: 先判断结构,再判断对应数值。

2.1 递归——DFS(深度优先)

四种情况分类讨论:

  1. 根都为空→ True
  2. 根一个为空,一个不为空→ False
  3. 根都不为空
    1. 根节点值不同→ False
    2. 根节点值相同→ 左右递归继续判断

时间复杂度: O(min(m, n)),其中 m 和 n 分别是两个二叉树的节点数。对两个二叉树同时进行深度优先搜索,只有当两个二叉树中的对应节点都不为空时才会访问到该节点,因此被访问到的节点数不会超过较小的二叉树的节点数。

空间复杂度: O(min(m, n)),其中 m 和 n 分别是两个二叉树的节点数。空间复杂度取决于递归调用的层数,递归调用的层数不会超过较小的二叉树的最大高度,最坏情况下,二叉树的高度等于节点数。

# Definition for a binary tree node.
# class TreeNode(object):
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution(object):
    def isSameTree(self, p, q):
        """
        :type p: TreeNode
        :type q: TreeNode
        :rtype: bool
        """
        if not p and not q:  # 都为空→ True
            return True
        elif not p or not q:  # 一个为空,一个不为空→ False
            return False
        elif p.val != q.val:  # 都不为空,但根节点值不同→ False
            return False
        else:  # 都不为空,根节点值相同→ 左右递归继续判断
            return self.isSameTree(p.left, q.left) and self.isSameTree(p.right, q.right)

2.2 迭代——BFS(广度优先)

一层一层地比较,用双边队列。

在这里插入图片描述

步骤:

  1. 根都为空→ True

  2. 根一个为空,一个不为空→ False

  3. 先建立两个双边队列,队列初值分别为两个根。

  4. 队列都不为空: (直到两个队列其中一个空了)

    1. 出队节点 (首次为根节点) 值不同→ False

    2. 出队节点 (首次为根节点) 值相同:

      1. 获取出队节点的两个孩子
      2. 出队节点的两个孩子依次从右侧进入队列。
        入队前比较结构(一个空一个非空,即为结构不同),入队后比较数值
  5. 判断两队列是否都空了

    1. 都空了→ True
    2. 一个空了,一个没空→ False

时间复杂度: O(min(m,n)),其中 m 和 n 分别是两个二叉树的节点数。对两个二叉树同时进行广度优先搜索,只有当两个二叉树中的对应节点都不为空时才会访问到该节点,因此被访问到的节点数不会超过较小的二叉树的节点数。

空间复杂度: O(min(m,n)),其中 m 和 n 分别是两个二叉树的节点数。空间复杂度取决于队列中的元素个数,队列中的元素个数不会超过较小的二叉树的节点数。

# Definition for a binary tree node.
# class TreeNode(object):
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution:
    def isSameTree(self, p, q):
        """
        :type p: TreeNode
        :type q: TreeNode
        :rtype: bool
        """
        if not p and not q:  # 根都为空→ True
            return True
        if not p or not q:  # 根一个为空一个非空→ False
            return False
        
        # 接下来就是根都不为空的情况了
        
        # 先建立两个双边队列,队列初值为两个根
        queue1 = collections.deque([p])
        queue2 = collections.deque([q])
        
        while queue1 and queue2:  # 其中一个空了就退出
            # 获取左侧出队节点
            node1 = queue1.popleft()
            node2 = queue2.popleft()
            
            # 比较出队的两个节点的数值(第一次出队的两个节点就是根节点)
            if node1.val != node2.val:
                return False
            
            # 获取孩子们的节点
            left1, right1 = node1.left, node1.right
            left2, right2 = node2.left, node2.right
            
            # 接下来孩子要入队,入队前比较结构
            if (not left1) ^ (not left2):
                return False
            if (not right1) ^ (not right2):
                return False
            
            # 结构相同,依次入队,同时也要注意空值情况,空值不入队。
            if left1:
                queue1.append(left1)
            if right1:
                queue1.append(right1)
            if left2:
                queue2.append(left2)
            if right2:
                queue2.append(right2)
                
            # 至此,队列更新完成,开始第二次循环
            
            
        # 都空了→ True;一个空了一个非空→ False
        return (not queue1) and (not queue2)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值