Stefan Pochmann 的上帝之手(8)

100. 相同的树

给定两个二叉树,编写一个函数来检验它们是否相同。

如果两个树在结构上相同,并且节点具有相同的值,则认为它们是相同的。
示例 1:

输入:

           1         1
          / \       / \
         2   3     2   3

        [1,2,3],   [1,2,3]

输出: true
示例 2:

输入:

           1         1
          /           \
         2             2

        [1,2],     [1,null,2]

输出: false
示例 3:

输入:

           1         1
          / \       / \
         2   1     1   2

        [1,2,1],   [1,1,2]

输出: false

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/same-tree

普通写法1:深度优先搜索(7行)

def isSameTree(self, p: TreeNode, q: TreeNode) -> bool:
    if not p and not q:
        return True
    if not p or not q:
        return False
    if p.val != q.val:
        return False
    return self.isSameTree(p.left, q.left) and self.isSameTree(p.right, q.right)

思路:判断当下节点是否相同,而后判断左孩子和右孩子是否相同。如果pq都是null则当下相同;pq有一个是null则不同;否则看二者value是否相同。

普通写法2:广度优先搜索(17行)

def isSameTree(self, p: TreeNode, q: TreeNode) -> bool:
    def check(p, q):
        if not p and not q:
            return True
        if not q or not p:
            return False
        if p.val != q.val:
            return False
        return True
    deq = deque([(p, q)])
    while deq:
        p, q = deq.popleft()
        if not check(p, q):
            return False
        if p:
            deq.append((p.left, q.left))
            deq.append((p.right, q.right))
    return True

思路:用一个双边队列将当下节点的孩子放在队列里,每次都查看当前队首是否相同。

大神写法1:深度优先搜索(3行)

def isSameTree(self, p: TreeNode, q: TreeNode) -> bool:
    if p and q:
        return p.val == q.val and self.isSameTree(p.left, q.left) and self.isSameTree(p.right, q.right)
    return p is q

思路与普通写法1一致。return p is q等价于return True if p == None and q == None else False

大神写法2:广度优先搜索(3行)

def isSameTree(self, p: TreeNode, q: TreeNode) -> bool:
    def t(n):
        return n and (n.val, t(n.left), t(n.right))
    return t(p) == t(q)

将所有的节点展成元组的形式,(root, left, right)。由于and只在前项为真时返回后项的逻辑值,所以遇到空节点会返回空。
举例,如果二叉树p的形状是:

           1
          / \
         2   3
        /
       4

print(t(p))返回

(1, (2, (4, None, None), None), (3, None, None))

这里的(n.val, t(n.left), t(n.right))换成[n.val, t(n.left), t(n.right)]也可以。

上帝之手(1行)

def isSameTree(self, p, q):
    return p and q and p.val == q.val and all(map(self.isSameTree, (p.left, p.right), (q.left, q.right))) or p is q

思路与深度优先搜索一致。
上述所有写法的时间复杂度(除大神写法2)都是O(min(m,n))其中m,n表示两棵树的叶子节点数。如果先遍历两棵树再比较,也包括大神写法2,复杂度是O(max(m,n))

你可能感兴趣的:(Stefan Pochmann 的上帝之手(8))