100. 相同的树
题目描述
给你两棵二叉树的根节点 p
和 q
,编写一个函数来检验这两棵树是否相同。
如果两个树在结构上相同,并且节点具有相同的值,则认为它们是相同的。
示例 1:
输入:p = [1,2,3], q = [1,2,3]
输出:true
示例 2:
输入:p = [1,2], q = [1,null,2]
输出:false
示例 3:
输入:p = [1,2,1], q = [1,1,2]
输出:false
提示:
- 两棵树上的节点数目都在范围
[0, 100]
内 -104 <= Node.val <= 104
解法
方法一:DFS
我们可以使用 DFS 递归的方法来解决这个问题。
首先判断两个二叉树的根节点是否相同,如果两个根节点都为空,则两个二叉树相同,如果两个根节点中有且只有一个为空,则两个二叉树一定不同。如果两个根节点都不为空,则判断它们的值是否相同,如果不相同则两个二叉树一定不同,如果相同,则分别判断两个二叉树的左子树是否相同以及右子树是否相同。当以上所有条件都满足时,两个二叉树才相同。
时间复杂度 \(O(\min(m, n))\),空间复杂度 \(O(\min(m, n))\)。其中 \(m\) 和 \(n\) 分别是两个二叉树的节点个数。空间复杂度主要取决于递归调用的层数,递归调用的层数不会超过较小的二叉树的节点个数。
方法二:BFS
我们也可以使用 BFS 迭代的方法来解决这个问题。
首先将两个二叉树的根节点分别加入两个队列。每次从两个队列各取出一个节点,进行如下比较操作。如果两个节点的值不相同,则两个二叉树的结构一定不同,如果两个节点的值相同,则判断两个节点的子节点是否为空,如果只有一个节点的左子节点为空,则两个二叉树的结构一定不同,如果只有一个节点的右子节点为空,则两个二叉树的结构一定不同,如果左右子节点的结构相同,则将两个节点的左子节点和右子节点分别加入两个队列,对于下一次迭代,将从两个队列各取出一个节点进行比较。当两个队列同时为空时,说明我们已经比较完了所有节点,两个二叉树的结构完全相同。
时间复杂度 \(O(\min(m, n))\),空间复杂度 \(O(\min(m, n))\)。其中 \(m\) 和 \(n\) 分别是两个二叉树的节点个数。空间复杂度主要取决于队列中的元素个数,队列中的元素个数不会超过较小的二叉树的节点个数。
Python3
DFS:
# Definition for a binary tree node.
# 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: TreeNode, q: TreeNode) -> bool:if not p and not q:return Trueelif not p or not q:return Falseelif p.val != q.val:return Falseelse:return self.isSameTree(p.left, q.left) and self.isSameTree(p.right, q.right)
BFS:
# Definition for a binary tree node.
# 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: TreeNode, q: TreeNode) -> bool:if p == q:return Trueif p is None or q is None:return Falseq1, q2 = deque([p]), deque([q])while q1 and q2:a, b = q1.popleft(), q2.popleft()if a.val != b.val:return Falsela, ra = a.left, a.rightlb, rb = b.left, b.rightif (la and not lb) or (lb and not la):return Falseif (ra and not rb) or (rb and not ra):return Falseif la:q1.append(la)q2.append(lb)if ra:q1.append(ra)q2.append(rb)return True
C++
/*** Definition for a binary tree node.* struct TreeNode {* int val;* TreeNode *left;* TreeNode *right;* TreeNode() : val(0), left(nullptr), right(nullptr) {}* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}* };*/
class Solution {
public:bool isSameTree(TreeNode* p, TreeNode* q) {if (p == nullptr && q == nullptr) {return true;} else if (p == nullptr || q == nullptr) {return false;} else if (p->val != q->val) {return false;} else {return isSameTree(p->left, q->left) && isSameTree(p->right, q->right);}}
};
/*** Definition for a binary tree node.* struct TreeNode {* int val;* TreeNode *left;* TreeNode *right;* TreeNode() : val(0), left(nullptr), right(nullptr) {}* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}* };*/
class Solution {
public:bool isSameTree(TreeNode* p, TreeNode* q) {if (p == q) return true;if (!p || !q) return false;queue<TreeNode*> q1{{p}};queue<TreeNode*> q2{{q}};while (!q1.empty() && !q2.empty()){p = q1.front();q = q2.front();if (p->val != q->val) return false;q1.pop();q2.pop();TreeNode *la = p->left, *ra = p->right;TreeNode *lb = q->left, *rb = q->right;if ((la && !lb) || (lb && !la)) return false;if ((ra && !rb) || (rb && !ra)) return false;if (la){q1.push(la);q2.push(lb);}if (ra){q1.push(ra);q2.push(rb);}}return true;}
};