力扣 | 100. 相同的树
题目截图
如果两个二叉树完全相同那么他们的结构和每个节点的值都相同。
当两个二叉树都为空时,两个二叉树相同。
当一个二叉树为空,一个二叉树不为空时,两个二叉树不相同。
当二叉树某一节点相同时,再看他们的其他节点是否相同。
利用递归的方法,设置终止条件。
当p、q节点都为空时,返回True。
当p、q节点有一个为空,有一个不为空时,返回False。
当p、q节点的值不相同时,返回False。
当p、q节点有的值相同时,继续判断其左孩子和右孩子的情况。
最后取其并集,只有全真结果才是True。否则中间为直接返回False。
class Solution:
def isSameTree(self, p: Optional[TreeNode], q: Optional[TreeNode]) -> bool:
if p == None and q == None:
return True
if p == None or q == None:
return False
if p.val != q.val :
return False
else:
return self.isSameTree(p.right,q.right) & self.isSameTree(p.left,q.left)
时间复杂度:
空间复杂度:
其中和分别是两二叉树的节点数。
from typing import Optional,List
class TreeNode:
def __init__(self, val=0, left=None, right=None):
self.val = val
self.left = left
self.right = right
class Solution:
def isSameTree(self, p: Optional[TreeNode], q: Optional[TreeNode]) -> bool:
if p == None and q == None:
return True
if p == None or q == None:
return False
if p.val != q.val :
return False
else:
return self.isSameTree(p.right,q.right) & self.isSameTree(p.left,q.left)
class main:
a = Solution()
p3 = TreeNode(6, left=None, right=None)
p2 = TreeNode(4, left=p3, right=None)
p = TreeNode(1, left = None, right= p2)
q3 = TreeNode(6, left=None, right=None)
q2 = TreeNode(2, left=q3, right=None)
q = TreeNode(1, left = None, right= q2)
b = a.isSameTree(p,q)
print(b)
if __name__ == '__main__':
main()
判断二叉树是否为空,这一部分与深度优先算法相同。
然后
使用两个队列分别存储两个二叉树的节点。初始时将两个二叉树的根节点分别加入两个队列。每次从两个队列各取出一个节点比较。
比较两个节点的值:
1.如果两个节点的值不相同则两个二叉树一定不同;
2.如果两个节点的值相同,则判断两个节点的子节点是否为空,
3.如果只有一个节点的左子节点为空,或者只有一个节点的右子节点为空,则两个二叉树的结构不同,因此两个二叉树一定不同;
4.如果两个节点的子节点的结构相同,则将两个节点的非空子节点分别加入两个队列,子节点加入队列时需要注意顺序,如果左右子节点都不为空,则先加入左子节点,后加入右子节点。
如果搜索结束时两个队列同时为空,则两个二叉树相同。如果只有一个队列为空,则两个二叉树的结构不同,因此两个二叉树不同。
class Solution:
def isSameTree(self, p: TreeNode, q: TreeNode) -> bool:
if not p and not q:
return True
if not p or not q:
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)
return not queue1 and not queue2
参见Python文档 | collections
collections是Python的一个集合模块,提供了一些集合方法。
deque函数,双向队列。
collections.deque([iterable[, maxlen]) | 返回一个新的双向队列对象,从左到右初始化(用方法append()) ,从 iterable (迭代对象) 数据创建。如果 iterable 没有指定,新队列为空。 |
append(x) | 添加x到队列右端。 |
appendleft(x) | 添加x到队列左端 |
pop() | 移去并且返回一个元素,deque最右端的一个。如果没有就会引发IndexError |
popleft() | 移去并且返回一个元素,deque最左端的一个。如果没有就会引发IndexError |