【问题标题】:Time complexity of KMP algorithmKMP算法的时间复杂度
【发布时间】:2014-02-09 05:04:49
【问题描述】:

我正在尝试使用 KMP 算法实现 strstr。这是维基百科中给出的算法。 KMP算法的时间复杂度为O(n),其中n是较大字符串的大小。

vector<int> KMP(string S, string K)
{
    vector<int> T(K.size() + 1, -1);
    vector<int> matches;

    if(K.size() == 0)
    {
        matches.push_back(0);
        return matches;
    }
    for(int i = 1; i <= K.size(); i++)
    {
        int pos = T[i - 1];
        while(pos != -1 && K[pos] != K[i - 1]) pos = T[pos];
        T[i] = pos + 1;
    }

    int sp = 0;
    int kp = 0;
    while(sp < S.size())
    {
        while(kp != -1 && (kp == K.size() || K[kp] != S[sp])) kp = T[kp];
        kp++;
        sp++;
        if(kp == K.size()) matches.push_back(sp - K.size());
    }

    return matches;
}

我不明白这个算法的复杂度是 O(n)。谁能解释一下这段代码的复杂度是 O(n) 吗?

【问题讨论】:

  • 你认为这还会是什么并解释一下?
  • 我认为填充数组 T 是 O(m^2),第二部分是 O(n*m),其中 m 是较小字符串的大小。
  • 这可能会有所帮助:wiki: KMP.

标签: c++ string algorithm time-complexity


【解决方案1】:

我认为您担心的是,在这两种情况下,每次外循环迭代可能会执行多达 m 次内循环,从而导致您提到的最坏情况的复杂性。事实上,这不可能发生。

看第一个循环可以归纳地注意到,由于 T[] 被初始化为 -1,我们有 T[0]

现在转到第二个嵌套循环,看到 kp 每次外循环迭代只增加一次,而内循环只能减少它。由于 kp 以 -1 为界并从 0 开始,在方法的整个生命周期中,我们总共只能比外循环迭代多执行一次内循环迭代,因为否则 kp 最终会比 - 小得多1.所以第二个嵌套循环总共只需花费 O(n)。

第一个嵌套循环看起来比较棘手,直到您注意到在外部循环开始时从 T[i - 1] 读取 pos,然后在结尾处写为 T[i] = pos + 1,所以 pos 是等价的到我们刚刚分析的嵌套循环中的 kp 并且相同的参数表明成本最多为 O(K.size())。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-09
    • 1970-01-01
    • 1970-01-01
    • 2013-12-31
    相关资源
    最近更新 更多