2010-09-30 2 views
3

Как найти самый длинный префикс палиндрома строки в O (n)?Самый длинный префикс палиндрома

+3

Это звучит как домашнее задание вопрос. Если это так, он должен быть помечен как таковой. –

+1

Определите самый длинный префикс палиндрома. А должно ли время быть связано O (n) или памятью? И это домашнее задание? –

+1

Я думаю, что этот ответ является toyota –

ответ

1

решения для более общей проблемы, а не префикс, но подстрока, в О (п):

http://www.akalin.cx/2007/11/28/finding-the-longest-palindromic-substring-in-linear-time/

Второй результат на Google для "длинной палиндромности префикса" ....

Или решение с помощью суффиксов деревьев:

http://www.allisons.org/ll/AlgDS/Tree/Suffix/

+0

Имеет функцию 'fastLongestPalindromes (..)' по ссылке на akalin.cx на самом деле 'O (n)' наихудшая сложность случая? Я вижу две вложенные петли. –

+0

Не читал все, кроме 2 вложенных циклов, это не означает квадратичную сложность. Продолжение в начале функции должно гарантировать, что внутренний цикл выполняется только в нескольких случаях и что общая сложность каждого выполнения этого цикла равна O (n). –

5

Используйте rolling hash. Если a ваша строка, пусть ha[x] быть хэш-первых x символов в a вычисленных слева направо, и пусть hr[x] быть хэш-первых x символов в s вычисленных справа налево. Вас интересует последняя позиция i, для которой hf[i] = hb[i].

код в C (используйте два хэши для каждого направления, чтобы избежать ложных срабатываний):

int match = n - 1; 

int ha1 = 0, ha2 = 0, hr1 = 0, hr2 = 0; 
int m1 = 1, m2 = 1; 
for (int i = 0; a[i]; ++i) 
{ 
    ha1 = (ha1 + m1*a[i]) % mod1; 
    ha2 = (ha2 + m2*a[i]) % mod2; 

    hr1 = (a[i] + base1*hr1) % mod1; 
    hr2 = (a[i] + base2*hr2) % mod2; 

    m1 *= base1, m1 %= mod1; 
    m2 *= base2, m2 %= mod2; 

    if (ha1 == hr1 && ha2 == hr2) 
     match = i; 
} 
+0

Я думаю, что часть «справа налево» отсутствует в примере кода ... ('i' идет слева направо, и вы получаете доступ только к' a [i] '. –

+0

@Andre Holzner -' i' идет только слева направо. На каждом шаге 'i' вы будете иметь длину текущего самого длинного палиндромного префикса, хранящегося в' match'. Только катящиеся хеши идут в обоих направлениях. – IVlad

+0

+1, Знаю, что это называлось «катящимся хешем». Но я даже два хэша не гарантирует, что каждое положительное значение «истинно» (не говоря уже о таких необычных коэффициентах :)). Просто потому, что для некоторой длины _n_ существует больше n-символьных строк, чем разные пары чисел int _ (ha1, ha2) _. И если вы проверите каждое положительное число, вы получите O (n^2) на равномерной строке ('aaaaaaaa ...'). –

Смежные вопросы