Хорошо! Вот моя вторая попытка.
Идея состоит в том, что мы хотим узнать, сколько символов в конце строки можно повторно использовать при добавлении дополнительных символов для завершения палиндрома. Для этого мы будем использовать модификацию алгоритма сопоставления строк KMP. Используя KMP, мы ищем обратную сторону исходной строки. Как только мы дойдем до самого конца строки, у нас будет как можно больше совпадений между обратной стороной строки и исходной строкой, которая встречается в конце строки. Например:
HELLO
O
1010
010
3202
202
1001
1001
На этом этапе KMP обычно говорит «нет совпадений», если исходная строка не была палиндромом. Однако, поскольку в настоящее время мы знаем, какая часть обратной стороны строки была сопоставлена, мы можем вместо этого просто вычислить, сколько символов все еще отсутствует, а затем прикрепить их к концу строки. В первом случае нам не хватает LLEH
. Во втором случае нам не хватает 1
. В третьем нам не хватает 3
. В последнем случае мы ничего не упускаем, поскольку исходная строка - это палиндром.
Время выполнения этого алгоритма - это время выполнения стандартного поиска KMP плюс время, необходимое для переворота строки: O (n) + O (n) = O (n).
Итак, теперь рассуждаем о правильности. Это потребует некоторых усилий. Рассмотрим оптимальный ответ:
| original string | | extra characters |
Предположим, мы читаем это в обратном порядке от конца, что означает, что мы читаем, по крайней мере, обратную сторону исходной строки. Часть этой перевернутой струны проходит назад внутрь самой исходной струны. Фактически, чтобы минимизировать количество добавляемых символов, это должно быть максимально возможное количество символов, которое оканчивается самой строкой. Мы можем увидеть это здесь:
| original string | | extra characters |
| overlap |
Итак, что происходит на нашем шаге KMP? Что ж, при поиске перевернутой строки внутри себя, KMP всегда будет сохранять как можно дольше совпадение, поскольку оно работает по строке. Это означает, что, когда KMP достигает конца строки, совпадающая часть, которую он поддерживает, будет самым длинным из возможных совпадений, поскольку KMP перемещает вперед только начальную точку совпадения кандидата в случае сбоя. Следовательно, у нас есть максимально возможное перекрытие, поэтому мы получим минимально возможное количество символов, необходимое в конце.
Я не уверен на 100%, что это работает, но похоже, что это работает во всех случаях, когда я могу это сделать. Доказательство правильности кажется разумным, но оно немного сложное, потому что формальное доказательство на основе KMP, вероятно, будет немного сложным.
Надеюсь это поможет!
person
templatetypedef
schedule
11.03.2012
str + str.reverse()
. но я сомневаюсь, что это мин - person jb.   schedule 10.03.2012