1. 程式人生 > >《程式設計師程式碼面試指南》判斷t1樹是否包含t2樹的全部拓撲結構

《程式設計師程式碼面試指南》判斷t1樹是否包含t2樹的全部拓撲結構

題目:

給定彼此獨立的兩棵樹頭結點分別為t1和t2,判斷t1樹是否包含t2樹的全部拓撲結構。

t1樹包含t2樹的全部拓撲結構,所以返回true。

解答:

如果t1中某棵子樹節點的值與t2頭節點的值一樣,則從這兩個頭結點開始匹配,匹配的每一步都讓t1上的節點跟著t2的節點先序遍歷移動,每移動一步,都檢查t1的當前節點是否和t2的當前節點值一樣。比如,題目中舉的例子,t1的節點2與t2的節點2匹配,然後t1跟著t2向左,發現t1中的節點4與t2中的節點4匹配,t1跟著t2繼續向左,發現t1中的8和t2中的8匹配,此時t2回到t2中的節點2,t1也回到t1中的節點2,然後,t1跟著t2向右,發現t1中的節點與t2中的節點5匹配。t2匹配完畢,結果返回true。如果匹配中出現不匹配的情況,直接返回false,說明t1從當前節點開始,無法與t2匹配,那麼去尋找t1的下一棵子樹。t1的每棵子樹上都有可能匹配出t2,所以需要都檢查一遍。

所以,如果t1的節點數為N,t2的節點數為M,該方法的時間複雜度為O(N*M)。

public class Contains {
    public class Node{
        public int value;
        public Node left;
        public Node right;
        public Node(int data){
            this.value = data;
        }
    }
    public boolean contains(Node t1, Node t2){
        return check(t1,t2) || contains(t1.left, t2) || contains(t1.right, t2);
    }
    public boolean check(Node h, Node t2){
        if(t2 == null){
            return true;
        }
        if(h == null || h.value != t2.value){
            return false;
        }
        return check(h.left, t2.left) && check(h.right, t2.right);
    }

    public static void main(String[] args) {

    }
}

參考資料:《程式設計師面試程式碼指南》左程雲 著