簡體   English   中英

這種通配符匹配算法的時間復雜度是多少?

[英]What's time complexity of this algorithm for Wildcard Matching?

通配符匹配
實現通配符模式匹配並支持' '和' * '。

  • '?' 匹配任何單個字符。
  • '*'匹配任何字符序列(包括空序列)。

匹配應覆蓋整個輸入字符串(不是部分)。

函數原型應該是:
bool isMatch(const char * s,const char * p)

一些例子:

  • isMatch(“aa”,“a”)→false
  • isMatch(“aa”,“aa”)→是的
  • isMatch(“aaa”,“aa”)→false
  • isMatch(“aa”,“*”)→true
  • isMatch(“aa”,“a *”)→true
  • isMatch(“ab”,“?*”)→true
  • isMatch(“aab”,“c * a * b”)→false

題:

  • 時間復雜度是多少?
  • 什么是空間復雜性?

我個人認為

  • 時間復雜度高度依賴於“輸入”,不能像T = O(?)那樣寫出來。
  • 空間復雜度= O(min(sLen,pLen)),因為最大遞歸深度= O(min(sLen,pLen))。

試過:
寫出時間復雜度表達式,然后繪制遞歸樹:

TC Expression => T(n) = T(n - 1) + O(1),            when pChar == '?' or pChar == sChar,
                      = T(n - 1) + T(n - 1) + O(1), when pChar == '*'.

我試圖繪制遞歸樹,但無法弄清楚如何根據這種時間復雜度表達式繪制它。

附加問題:
准確地說,我希望知道如何計算這種遞歸的時間復雜度,這種遞歸具有基於輸入的多不可預見的分支。

注意:

  • 我知道迭代解決方案和遞歸解決方案,但無法弄清楚如何計算遞歸解決方案的時間復雜度。
  • 這不是功課,這個問題來自“leetcode.com”,我只是希望知道如何計算這種特殊遞歸的時間復雜度的方法。


代碼: Java, 解決方案:遞歸。

public class Solution {
    public boolean isMatch(String s, String p) {
        // Input checking.
        if (s == null || p == null) return false;

        int sLen = s.length();
        int pLen = p.length();

        return helper(s, 0, sLen, p, 0, pLen);
    }

    private boolean helper(String s, int sIndex, int sLen,
                           String p, int pIndex, int pLen) {
        // Base case.
        if (sIndex >= sLen && pIndex >= pLen) return true;
        else if (sIndex >= sLen) {
            // Check whether the remaining part of p all "*".
            while (pIndex < pLen) {
                if (p.charAt(pIndex) != '*') return false;
                pIndex ++;
            }
            return true;

        } else if (pIndex >= pLen) {
            return false;
        }

        char sc = s.charAt(sIndex);
        char pc = p.charAt(pIndex);

        if (pc == '?' || pc == sc) {
            return helper(s, sIndex + 1, sLen, p, pIndex + 1, pLen);

        } else if (pc == '*') {
            return helper(s, sIndex, sLen, p, pIndex + 1, pLen) ||
                   helper(s, sIndex + 1, sLen, p, pIndex, pLen);

        } else return false;
    }
}

為了在最壞的情況下獲得上限(即大O),您需要假設最壞的情況。 對於長度為s的字符串與長度為p的模式匹配的漸近運行時間的上限的正確遞歸如下。

T(s, p) | s == 0 || p == 0 = 1
        | s >  0 && p >  0 = 1 + max(T(s, p - 1) + T(s - 1, p),  // *
                                     T(s - 1, p - 1))            // ? or literal

解決這樣的雙變量復發可能很棘手。 在這種特殊情況下,人們可以通過歸納相當容易地表明T在兩個參數中都是非遞減的,因此我們可以簡化最大值。

T(s, p) | s == 0 || p == 0 = 1
        | s >  0 && p >  0 = 1 + T(s, p - 1) + T(s - 1, p)

現在,有經驗的人可以認識到與二項式系數的遞歸有很強的相似性,並使(無可否認的是有點神奇的)替換s = n - kp = kT(s, p) = 2 U(n, k) - 1

2 U(n, k) - 1 | n == k || k == 0 = 1
              | n >  k && k >  0 = 1 + 2 U(n - 1, k - 1) - 1 + 2 U(n - 1, k) - 1

U(n, k) | n == k || k == 0 = 1
        | n >  k && k >  0 = U(n - 1, k - 1) + U(n - 1, k)

我們得出結論, T(s, p) = 2 U(s + p, p) - 1 = 2 ((s + p) choose p) - 1 = O(2^(s + p)/sqrt(s + p))通過斯特林的近似(這是單個量s + p可能的最佳大O界限,但如果我寫大-Theta則令人困惑)。

到目前為止,我們只證明了T(s, p)是一個上界。 由於*是更麻煩的情況,最壞情況的想法出現了:使模式全部* s。 我們必須要小心一點,因為如果匹配成功,那么可能會有一些短路。 但是,防止匹配只需要很少的時間:考慮字符串0000000000和模式**********1 (根據需要調整0 s和*的數量)。 此示例顯示引用的邊界在多項式因子內是緊的(可忽略不計,因為運行時間已經是指數)。


為了獲得上限,沒有必要幾乎精確地計算出這些重現。 例如,我可能猜測T(s, p) <= 3^(s + p)並繼續通過歸納驗證聲明。

T(s, p) | s = 0 || p = 0  = 1 <= 3^(s + p)                 // base case
        | s > 0 || p > 0  = 1 + T(s, p - 1) + T(s - 1, p)  // induction
                         <= 3^(s + p - 1) + 3^(s + p - 1) + 3^(s + p - 1)
                          = 3^(s + p)

現在, 3^(s + p)是一個有效的上限,但鑒於這個答案的其余部分,它並不緊張。 一個人現在可以在邊界尋找浪費; 1 <= 3^(s + p - 1)是一個粗略的高估,並且通過一些技巧,我們可以得到指數基數2

然而,更重要的業務秩序是獲得指數下限。 從繪制上面的壞例子的遞歸樹,我可能猜想T(s, p) >= 2^min(s, p) 這可以通過歸納驗證。

T(s, p) | s = 0 || p = 0  = 1 >= 2^min(s, p) = 2^0 = 1             // base case
        | s > 0 && p > 0  = 1 +     T(s, p - 1) +     T(s - 1, p)  // induction
                         >=     2^min(s, p - 1) + 2^min(s - 1, p)
                         >= 2^(min(s, p) - 1) + 2^(min(s, p) - 1)
                          = 2^min(s, p)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM