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)先搜索
思路:
??如果兩個二叉樹都為空,則兩個二叉樹相同贫母。如果兩個二叉樹中有且只有一個為空文兑,則兩個二叉樹一定不相同。
??如果兩個二叉樹都不為空腺劣,那么首先判斷它們的根節(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ù)缎浇。
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末扎拣,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子素跺,更是在濱河造成了極大的恐慌鹏秋,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,188評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件亡笑,死亡現(xiàn)場離奇詭異侣夷,居然都是意外死亡,警方通過查閱死者的電腦和手機仑乌,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,464評論 3 395
  • 文/潘曉璐 我一進店門百拓,熙熙樓的掌柜王于貴愁眉苦臉地迎上來琴锭,“玉大人,你說我怎么就攤上這事衙传【鎏” “怎么了?”我有些...
    開封第一講書人閱讀 165,562評論 0 356
  • 文/不壞的土叔 我叫張陵蓖捶,是天一觀的道長地回。 經(jīng)常有香客問我,道長俊鱼,這世上最難降的妖魔是什么刻像? 我笑而不...
    開封第一講書人閱讀 58,893評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮并闲,結(jié)果婚禮上细睡,老公的妹妹穿的比我還像新娘。我一直安慰自己帝火,他們只是感情好溜徙,可當我...
    茶點故事閱讀 67,917評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著犀填,像睡著了一般蠢壹。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上九巡,一...
    開封第一講書人閱讀 51,708評論 1 305
  • 那天知残,我揣著相機與錄音,去河邊找鬼比庄。 笑死求妹,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的佳窑。 我是一名探鬼主播制恍,決...
    沈念sama閱讀 40,430評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼神凑!你這毒婦竟也來了净神?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,342評論 0 276
  • 序言:老撾萬榮一對情侶失蹤溉委,失蹤者是張志新(化名)和其女友劉穎鹃唯,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體瓣喊,經(jīng)...
    沈念sama閱讀 45,801評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡坡慌,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,976評論 3 337
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了藻三。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片洪橘。...
    茶點故事閱讀 40,115評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡跪者,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出熄求,到底是詐尸還是另有隱情渣玲,我是刑警寧澤,帶...
    沈念sama閱讀 35,804評論 5 346
  • 正文 年R本政府宣布弟晚,位于F島的核電站忘衍,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏卿城。R本人自食惡果不足惜枚钓,卻給世界環(huán)境...
    茶點故事閱讀 41,458評論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望藻雪。 院中可真熱鬧秘噪,春花似錦狸吞、人聲如沸勉耀。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,008評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽便斥。三九已至,卻和暖如春威始,著一層夾襖步出監(jiān)牢的瞬間枢纠,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,135評論 1 272
  • 我被黑心中介騙來泰國打工黎棠, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留晋渺,地道東北人。 一個月前我還...
    沈念sama閱讀 48,365評論 3 373
  • 正文 我出身青樓脓斩,卻偏偏與公主長得像木西,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子随静,可洞房花燭夜當晚...
    茶點故事閱讀 45,055評論 2 355

推薦閱讀更多精彩內(nèi)容