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

我的思路

1.需要提前判断根节点

2.需要判断子节点是否相同,很复杂,代码也不够精简

3.关注的是当前节点,和子节点,显得很臃肿。。。

# Definition for a binary tree node.
# class TreeNode(object):
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None
'''
1.用一个栈来操作两棵树
2.每次入栈同时压入两棵树的节点
3.每次去除同时取出两棵树的节点,这样和操作一棵树是一样的。
'''
class Solution(object):
    def isSameTree(self, p, q):
        """
        :type p: TreeNode
        :type q: TreeNode
        :rtype: bool
        """
        if p is None and q is None:return True
        if p is None and q: return False
        if p and q is None :return False
        que = []
        que.append(p)
        que.append(q)
        while que:
            nodep = que.pop(0)
            nodeq = que.pop(0)
            #当前节点一定是存在的,只需要对比值是否相同就行
            if nodep.val!=nodeq.val:return False
                        
            #先是p,q的左子节点存在->入栈
            #(不管值对不对,这里只关心两棵树的子节点是否都存在,值的正确与否交给上一行代码)
            #然后列出两棵树的子节点不一致的情况(笨办法,全列出来了。。。因为有可能遇到叶子节点)           
            if nodep.left and nodeq.left:
                que.append(nodep.left)
                que.append(nodeq.left)
            elif nodep.left and nodeq.left is None:return False
            elif nodep.left is None and nodeq.left:return False
            if nodep.right and nodeq.right:
                que.append(nodep.right)
                que.append(nodeq.right)
            elif nodep.right and nodeq.right is None:return False
            elif nodep.right is None and nodeq.right : return False
        #全部没问题,返回True
        return True
            

题解1 - 只关注当前节点(栈实现)

# Definition for a binary tree node.
# class TreeNode(object):
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None
'''
1.同样是用一个栈来遍历两棵树
'''
class Solution(object):
    def isSameTree(self, p, q):
        """
        :type p: TreeNode
        :type q: TreeNode
        :rtype: bool
        """

        sk = []
        sk.append(p)
        sk.append(q)
        while sk:
            nodep = sk.pop(0)
            nodeq = sk.pop(0)                            
            '''
            两棵树的当前节点可能出现的几种情况
               p     q
            1.None,None (两个都为空)                    
            2. 3  ,None (一个不为空,一个空)            1.两个都为空(True)
            3.None, 3   (一个空,一个不为空)  --简化-->  2.其中一个为空(False)
            4. 3  , 2   (都不为空,但值不同)            3.值是否相同(False)
            5. 3  , 3   (正解)                        
            '''
            #第一种情况
            if nodep is None and nodeq is None:
                continue
            ##因为排除了两个都为空的情况,就只剩下(情况2,情况3)、情况4、(正解)
            #因此(情况2,情况3)只需要判断其中一个是否为None                        
            if nodep is None or nodeq is None or nodep.val!=nodeq.val:
                return False
                                
            #因为是关注的当前节点,所以空子节点也会入栈
            sk.append(nodep.left)
            sk.append(nodeq.left)
            
            sk.append(nodep.right)
            sk.append(nodeq.right)
        return True
            

题解2:递归实现

总结

1.在这道题中,用O(n)的复杂度同时遍历两颗树?

2.如何让空子节点入栈?

3.空子节点入栈的前提下,如何避免叶子节点空子节点入栈?

4.Python判断节点空和非空

https://www.cnblogs.com/alantu2018/p/8465884.html

原文地址:https://www.cnblogs.com/remly/p/11374515.html