100. Same Tree 判斷相同樹

題目鏈接
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)先搜索
思路:
??如果兩個(gè)二叉樹都為空,則兩個(gè)二叉樹相同。如果兩個(gè)二叉樹中有且只有一個(gè)為空,則兩個(gè)二叉樹一定不相同。
??如果兩個(gè)二叉樹都不為空,那么首先判斷它們的根節(jié)點(diǎn)的值是否相同,若不相同則兩個(gè)二叉樹一定不同,若相同,再分別判斷兩個(gè)二叉樹的左子樹是否相同以及右子樹是否相同。這是一個(gè)遞歸的過程,因此可以使用深度優(yōu)先搜索,遞歸地判斷兩個(gè)二叉樹是否相同,代碼如下:

/**
 * 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);
    }
};

復(fù)雜度分析:

  • 時(shí)間復(fù)雜度:O(min(m,n)),其中 m 和 n 分別是兩個(gè)二叉樹的節(jié)點(diǎn)數(shù)。對(duì)兩個(gè)二叉樹同時(shí)進(jìn)行深度優(yōu)先搜索,只有當(dāng)兩個(gè)二叉樹中的對(duì)應(yīng)節(jié)點(diǎn)都不為空時(shí)才會(huì)訪問到該節(jié)點(diǎn),因此被訪問到的節(jié)點(diǎn)數(shù)不會(huì)超過較小的二叉樹的節(jié)點(diǎn)數(shù)。
  • 空間復(fù)雜度:O(min(m,n)),其中 m 和 n 分別是兩個(gè)二叉樹的節(jié)點(diǎn)數(shù)。空間復(fù)雜度取決于遞歸調(diào)用的層數(shù),遞歸調(diào)用的層數(shù)不會(huì)超過較小的二叉樹的最大高度,最壞情況下,二叉樹的高度等于節(jié)點(diǎn)數(shù)。

解法二:廣度優(yōu)先搜索
??也可以通過廣度優(yōu)先搜索判斷兩個(gè)二叉樹是否相同。同樣首先判斷兩個(gè)二叉樹是否為空,如果兩個(gè)二叉樹都不為空,則從兩個(gè)二叉樹的根節(jié)點(diǎn)開始廣度優(yōu)先搜索。

使用兩個(gè)隊(duì)列分別存儲(chǔ)兩個(gè)二叉樹的節(jié)點(diǎn)。初始時(shí)將兩個(gè)二叉樹的根節(jié)點(diǎn)分別加入兩個(gè)隊(duì)列。每次從兩個(gè)隊(duì)列各取出一個(gè)節(jié)點(diǎn),進(jìn)行如下比較操作。

  • 比較兩個(gè)節(jié)點(diǎn)的值,如果兩個(gè)節(jié)點(diǎn)的值不相同則兩個(gè)二叉樹一定不同;
  • 如果兩個(gè)節(jié)點(diǎn)的值相同,則判斷兩個(gè)節(jié)點(diǎn)的子節(jié)點(diǎn)是否為空,如果只有一個(gè)節(jié)點(diǎn)的左子節(jié)點(diǎn)為空,或者只有一個(gè)節(jié)點(diǎn)的右子節(jié)點(diǎn)為空,則兩個(gè)二叉樹的結(jié)構(gòu)不同,因此兩個(gè)二叉樹一定不同;
  • 如果兩個(gè)節(jié)點(diǎn)的子節(jié)點(diǎn)的結(jié)構(gòu)相同,則將兩個(gè)節(jié)點(diǎn)的非空子節(jié)點(diǎn)分別加入兩個(gè)隊(duì)列,子節(jié)點(diǎn)加入隊(duì)列時(shí)需要注意順序,如果左右子節(jié)點(diǎn)都不為空,則先加入左子節(jié)點(diǎn),后加入右子節(jié)點(diǎn)。

如果搜索結(jié)束時(shí)兩個(gè)隊(duì)列同時(shí)為空,則兩個(gè)二叉樹相同。如果只有一個(gè)隊(duì)列為空,則兩個(gè)二叉樹的結(jié)構(gòu)不同,因此兩個(gè)二叉樹不同。參見代碼如下:

/**
 * 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();
    }
};

復(fù)雜度分析:

  • 時(shí)間復(fù)雜度:O(min(m,n)),其中 m 和 n 分別是兩個(gè)二叉樹的節(jié)點(diǎn)數(shù)。對(duì)兩個(gè)二叉樹同時(shí)進(jìn)行廣度優(yōu)先搜索,只有當(dāng)兩個(gè)二叉樹中的對(duì)應(yīng)節(jié)點(diǎn)都不為空時(shí)才會(huì)訪問到該節(jié)點(diǎn),因此被訪問到的節(jié)點(diǎn)數(shù)不會(huì)超過較小的二叉樹的節(jié)點(diǎn)數(shù)。
  • 空間復(fù)雜度:O(min(m,n)),其中 m 和 n 分別是兩個(gè)二叉樹的節(jié)點(diǎn)數(shù)。空間復(fù)雜度取決于隊(duì)列中的元素個(gè)數(shù),隊(duì)列中的元素個(gè)數(shù)不會(huì)超過較小的二叉樹的節(jié)點(diǎn)數(shù)。
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容