題目鏈接
tag:
- Easy剖张;
- DFS派阱;
- BFS诬留;
question:
??Given the roots of two binary trees p and q, write a function to check if they are the same or not.
Two binary trees are considered the same if they are structurally identical, and the nodes have the same value.
Example 1:
Input: p = [1,2,3], q = [1,2,3]
Output: true
Example 2:
Input: p = [1,2], q = [1,null,2]
Output: false
Example 3:
Input: p = [1,2,1], q = [1,1,2]
Output: false
Constraints:
- The number of nodes in both trees is in the range [0, 100].
- 104 <= Node.val <= 104
解法一:深度優(yōu)先搜索
思路:
??如果兩個二叉樹都為空,則兩個二叉樹相同贫母。如果兩個二叉樹中有且只有一個為空文兑,則兩個二叉樹一定不相同。
??如果兩個二叉樹都不為空腺劣,那么首先判斷它們的根節(jié)點的值是否相同绿贞,若不相同則兩個二叉樹一定不同,若相同橘原,再分別判斷兩個二叉樹的左子樹是否相同以及右子樹是否相同樟蠕。這是一個遞歸的過程,因此可以使用深度優(yōu)先搜索靠柑,遞歸地判斷兩個二叉樹是否相同寨辩,代碼如下:
/**
* 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) {
// 遞歸,深度優(yōu)先搜索
if (!p && !q) return true;
if (!p && q) return false;
if (p && !q) return false;
if (p->val != q->val) return false;
else return isSameTree(p->left, q->left) && isSameTree(p->right, q->right);
}
};
復雜度分析:
- 時間復雜度:O(min(m,n))歼冰,其中 m 和 n 分別是兩個二叉樹的節(jié)點數(shù)靡狞。對兩個二叉樹同時進行深度優(yōu)先搜索,只有當兩個二叉樹中的對應節(jié)點都不為空時才會訪問到該節(jié)點隔嫡,因此被訪問到的節(jié)點數(shù)不會超過較小的二叉樹的節(jié)點數(shù)甸怕。
- 空間復雜度:O(min(m,n)),其中 m 和 n 分別是兩個二叉樹的節(jié)點數(shù)腮恩∩液迹空間復雜度取決于遞歸調(diào)用的層數(shù),遞歸調(diào)用的層數(shù)不會超過較小的二叉樹的最大高度秸滴,最壞情況下武契,二叉樹的高度等于節(jié)點數(shù)。
解法二:廣度優(yōu)先搜索
??也可以通過廣度優(yōu)先搜索判斷兩個二叉樹是否相同荡含。同樣首先判斷兩個二叉樹是否為空咒唆,如果兩個二叉樹都不為空,則從兩個二叉樹的根節(jié)點開始廣度優(yōu)先搜索释液。
使用兩個隊列分別存儲兩個二叉樹的節(jié)點全释。初始時將兩個二叉樹的根節(jié)點分別加入兩個隊列。每次從兩個隊列各取出一個節(jié)點误债,進行如下比較操作浸船。
- 比較兩個節(jié)點的值妄迁,如果兩個節(jié)點的值不相同則兩個二叉樹一定不同;
- 如果兩個節(jié)點的值相同李命,則判斷兩個節(jié)點的子節(jié)點是否為空登淘,如果只有一個節(jié)點的左子節(jié)點為空,或者只有一個節(jié)點的右子節(jié)點為空项戴,則兩個二叉樹的結(jié)構(gòu)不同,因此兩個二叉樹一定不同槽惫;
- 如果兩個節(jié)點的子節(jié)點的結(jié)構(gòu)相同周叮,則將兩個節(jié)點的非空子節(jié)點分別加入兩個隊列,子節(jié)點加入隊列時需要注意順序界斜,如果左右子節(jié)點都不為空仿耽,則先加入左子節(jié)點,后加入右子節(jié)點各薇。
如果搜索結(jié)束時兩個隊列同時為空项贺,則兩個二叉樹相同。如果只有一個隊列為空峭判,則兩個二叉樹的結(jié)構(gòu)不同开缎,因此兩個二叉樹不同。參見代碼如下:
/**
* 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) {
// 廣度優(yōu)先搜索
if (!p && !q) return true;
if (!p && q) return false;
if (p && !q) return false;
queue<TreeNode*> queue1, queue2;
queue1.push(p);
queue2.push(q);
while (!queue1.empty() && !queue2.empty()) {
TreeNode* p1 = queue1.front();
queue1.pop();
TreeNode* q1 = queue2.front();
queue2.pop();
if (p1->val != q1->val) return false;
auto p1_left = p1->left, p1_right = p1->right;
auto q1_left = q1->left, q1_right = q1->right;
if ((!p1_left) ^ (!q1_left)) return false;
if ((!p1_right) ^ (!q1_right)) return false;
if (p1_left) queue1.push(p1_left);
if (p1_right) queue1.push(p1_right);
if (q1_left) queue2.push(q1_left);
if (q1_right) queue2.push(q1_right);
}
return queue1.empty() && queue2.empty();
}
};
復雜度分析:
- 時間復雜度:O(min(m,n))林螃,其中 m 和 n 分別是兩個二叉樹的節(jié)點數(shù)奕删。對兩個二叉樹同時進行廣度優(yōu)先搜索,只有當兩個二叉樹中的對應節(jié)點都不為空時才會訪問到該節(jié)點疗认,因此被訪問到的節(jié)點數(shù)不會超過較小的二叉樹的節(jié)點數(shù)完残。
- 空間復雜度:O(min(m,n)),其中 m 和 n 分別是兩個二叉樹的節(jié)點數(shù)横漏〗魃瑁空間復雜度取決于隊列中的元素個數(shù),隊列中的元素個數(shù)不會超過較小的二叉樹的節(jié)點數(shù)缎浇。