1. 程式人生 > >OptimalSolution(2)--二叉樹問題(4)子樹與拓撲結構

OptimalSolution(2)--二叉樹問題(4)子樹與拓撲結構

kmp ole 結點 mp算法 返回 str 序列 || 開始

  一、判斷t1樹是否包含t2樹全部的拓撲結構

          1
        /           2      3                       2
     /   \    /  \                   /      4    5  6    7                  4    5
   / \   /                         /
  8  9 10                         8                               返回:true

  解法(O(M×N)):如果t1中某棵子樹頭結點和t2頭結點的值一樣,則從這兩個頭結點開始匹配,匹配的每一步都是讓t1上的節點跟著t2的先序遍歷移動,每移動一步,都檢查t1的當前節點和t2當前節點的值是否一樣。如果匹配的過程中發現有不匹配的過程,直接返回false,那麽再去尋找t1的下一棵樹。

    public boolean contains(Node t1, Node t2) {
        return check(t1, t2) || contains(t1.left, t2) || contains(t1.right, t2);
    }

    private boolean check(Node h, Node t2) {
        if (t2 == null) return false;
        if (h == null || h.val != t2.val) return false;
        return check(h.left, t2.left) && check(h.right, t2.right);
    }

  二、判斷t1樹中是否有與t2樹拓撲結構完全相同的子樹

          1
        /           2      3                       2                          2
     /   \    /  \                   /  \                       / \
    4    5  6    7                  4    5                     4   5
    \   /                            \   /                      \ 
     8 9                              8  9  返回:true            8     返回:false

  如果t1的節點數為N,t2的節點數為M  

  1.時間復雜度為O(N×M)的方法:對於t1的每棵子樹,都去判斷是否與t2樹的拓撲結構完全一樣,這個過程的復雜度為O(M),t1的子樹一共有N棵,所以時間復雜度是O(N×M)

  2.時間復雜度為O(N+M)的方法:先將t1樹前序遍歷序列化成字符串“1!2!4!#!8!#!#!5!9!#!#!#!#!3!6!#!#!7!#!#!”,而t2樹前序遍歷序列化為字符串“2!4!#!8!#!#!5!9!#!#!”(t3樹前序遍歷序列化為字符串“2!4!#!8!#!#!5!#!#!”),也就是驗證t2str是否是t1str的子串即可,可以用KMP算法在線性時間內解決。所以t1序列化的時間復雜度為O(N),t2序列化的時間復雜度是O(M),KMP解決兩個字符串的匹配問題O(M+N),所以時間復雜度是O(M+N)。

  

  

OptimalSolution(2)--二叉樹問題(4)子樹與拓撲結構