Wikipedia утверждает, что таблицу функций сбоя можно вычислить в O (n) времени.
Посмотрим на его "каноническую" реализацию (в С++):
vector<int> prefix_function (string s) {
int n = (int) s.length();
vector<int> pi (n);
for (int i=1; i<n; ++i) {
int j = pi[i-1];
while (j > 0 && s[i] != s[j])
j = pi[j-1];
if (s[i] == s[j]) ++j;
pi[i] = j;
}
return pi;
}
Почему он работает в O (n) времени, даже если есть внутренний while-loop? Я не очень силен при анализе алгоритмов, так может кто-нибудь объяснить это?