Solution 1
一开始我想暴力地通过中序遍历序列比对解决,但是这样实际上无法确定绝对结构。因此需要通过递归解决。整个递归逻辑为:
- 如果两棵树的当前节点都是空的,相同
- 否则,如果两棵树有且只有一棵非空,不相同
- 否则,如果两棵树非空且值不相同,不相同
- 否则,向下递归检查当前子树的左节点和右节点
- 时间复杂度: O ( N ) O(N) O(N),其中 N N N为节点个数,最坏情况检查整棵树
- 空间复杂度: O ( N ) O(N) O(N),其中 N N N为节点个数,最坏情况下,这是一棵非常skew的树
/**
* 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);
}
}
};
Solution 2
【官方题解】将上述检查过程视为DFS,其实还可以实现为BFS。整个的检查逻辑为:
- 如果当前节点(BFS从队列取节点,必然非空)值不同,不相同
- 否则,如果当前节点的左节点同时为空或者右节点同时为空,相同
- 否则,如果当前节点的左节点有且只有一棵非空或者右节点有且只有一棵非空,不相同
- 否则,将存在的一侧放入队列
- 时间复杂度: O ( N ) O(N) O(N),其中 N N N为节点个数,最坏情况检查整棵树
- 空间复杂度: O ( N ) O(N) O(N),其中 N N N为节点个数,最坏情况下,这是一棵非常skew的树
/**
* 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;
}
queue <TreeNode*> qp, qq;
qp.push(p);
qq.push(q);
// cout << "NOW" << (p->val) << " " << (q->val) << endl;
while (!qp.empty() && !qq.empty()) {
auto curp = qp.front();
qp.pop();
auto curq = qq.front();
qq.pop();
// cout << "NOW" << (curp->val) << " " << (curq->val) << endl;
if (curp->val != curq->val) {
return false;
} else {
auto leftp = curp->left;
auto leftq = curq->left;
if (leftp != nullptr && leftq != nullptr) {
qp.push(leftp);
qq.push(leftq);
// cout << (leftp->val) << " " << (leftq->val);
} else if (leftp == nullptr ^ leftq == nullptr) {
return false;
}
auto rightp = curp->right;
auto rightq = curq->right;
if (rightp != nullptr && rightq != nullptr) {
qp.push(rightp);
qq.push(rightq);
// cout << "LOAD" << rightp->val << " " << rightq->val;
} else if (rightp == nullptr ^ rightq == nullptr) {
return false;
}
}
}
return qp.empty() && qq.empty();
}
};
Solution 3
Solution 1的Python实现
# 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: Optional[TreeNode], q: Optional[TreeNode]) -> bool:
if p is None and q is None:
return True
elif p is None or q is None:
return False
elif p.val != q.val:
return False
else:
return self.isSameTree(p.left, q.left) and self.isSameTree(p.right, q.right)
Solution 4
Solution 2的Python实现
# 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: Optional[TreeNode], q: Optional[TreeNode]) -> bool:
if p is None and q is None:
return True
elif p is None or q is None:
return False
qp = collections.deque([p])
qq = collections.deque([q])
# print(p.val, q.val)
while qp and qq:
curp = qp.popleft()
curq = qq.popleft()
# print("NOW", curp.val, curq.val)
if curp.val != curq.val:
return False
else :
leftp, leftq = curp.left, curq.left
if leftp is not None and leftq is not None:
qp.append(leftp)
qq.append(leftq)
# print("LEFT", leftp.val, leftq.val)
elif (leftp is None) ^ (leftq is None):
return False
rightp, rightq = curp.right, curq.right
if rightp is not None and rightq is not None:
qp.append(rightp)
qq.append(rightq)
# print("RIGHT", rightp.val, rightq.val)
elif (rightp is None) ^ (rightq is None):
return False
return not qp and not qq