【LeetCode每週一題】相同的樹

這次給大家帶來的是一道關於樹結構的題——相同的樹。該題是一道難度爲簡單的題目,考察的是對樹結構進行遍歷的理解。

描述

給定兩個二叉樹,編寫一個函數來檢驗它們是否相同。

如果兩個樹在結構上相同,並且節點具有相同的值,則認爲它們是相同的。

示例

示例1:

輸入:
[1,2,3]
[1,2,3]

輸出:
true

圖解:
  1      1
 / \    / \
2   3  2   3

示例2:

輸入:
[1,2]
[1,null,2]

輸出:
false

圖解:
  1      1
 /        \
2          2

示例3:

輸入:
[1,2,1]
[1,1,2]

輸出:
false

圖解:
  1      1
 / \    / \
2   1  1   2

解法一

比較容易想到且實現的一種解法就是利用遞歸進行實現。每次調用IsSameTree方法時判斷當前兩個結點是否相同(需要處理爲空的情況),若二者的值不同則不爲相同的樹;若二者的值相同,則通過IsSameTree方法對子結點繼續進行判斷。

public bool IsSameTree(TreeNode p, TreeNode q) {
    if (p == null && q == null)
    {
        return true;
    }
    else if (p == null || q == null)
    {
        return false;
    }

    return p.val == q.val && IsSameTree(p.left, q.left) && IsSameTree(p.right, q.right);
}

遞歸法對每個結點只訪問一次,時間複雜度爲O(N),且不需要輔助的內存空間,但需要額外的函數調用開銷。

解法二

同樣,我們也可以使用迭代的方法實現該題。在對樹使用迭代法進行遍歷時,需要使用額外的輔助空間存放尚未遍歷到的結點,這裏我們使用了兩個隊列做這個工作。

在開始時,要先把樹的根結點入隊。在每次迭代的過程中需要判斷當前結點的值是否相同(同樣也要處理爲空的情況),若二者的值不同則不是相同的樹;若二者的值相同則將子結點入隊,繼續進行下一輪迭代。

public bool IsSameTree(TreeNode p, TreeNode q) {
    Queue<TreeNode> pQueue = new Queue<TreeNode>();
    Queue<TreeNode> qQueue = new Queue<TreeNode>();

    pQueue.Enqueue(p);
    qQueue.Enqueue(q);

    while (pQueue.Count > 0 || qQueue.Count > 0)
    {
        TreeNode pNode = pQueue.Dequeue();
        TreeNode qNode = qQueue.Dequeue();

        if (pNode == null && qNode == null)
        {
            continue;
        } 
        else if (pNode == null || qNode == null || pNode.val != qNode.val)
        {
            return false;
        }

        pQueue.Enqueue(pNode.left);
        pQueue.Enqueue(pNode.right);
        qQueue.Enqueue(qNode.left);
        qQueue.Enqueue(qNode.right);
    }
        
    return true;
}

使用迭代法也只對每個結點訪問一次,時間複雜度爲O(N),另外需要對應的輔助存儲空間。在最優的情況下,空間複雜度爲O(log(N)),最壞情況下爲O(N)。

結束語

對於上述的示例有多種解法,如使用迭代法時可以只使用一個額外的輔助隊列存放結點,但爲了能讓大家快速理解便未進行相應的優化。

今天的內容就到這裏啦,我們下週再見👋~

歡迎大家關注我的公衆號“風紙”,或是掃下面的二維碼關注👇
風紙

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章