Раунд 2
На мой взгляд, с каждым новым персонажем есть три случая:
- Символ нарушает потенциальную симметрию, например, aab -> aabc
- Символ расширяет середину, например aab -> aabb
- Символ продолжает симметрию, например aab-> aaba
Предположим, у вас есть указатель, который отслеживает строку и указывает на последний символ, который продолжил потенциальный палиндром.
(я собираюсь использовать круглые скобки для обозначения заостренного символа)
Допустим, вы начинаете с aa (b) и получаете:
- 'a' (случай 3), вы перемещаете указатель на
слева и проверьте, является ли это «а» (это
является). Теперь у вас есть (а) б.
- «c» (случай 1), вы не ожидаете «c», в этом случае вы начинаете с начала и теперь у вас есть aab (c).
Действительно сложный случай - 2, потому что каким-то образом вы должны знать, что только что полученный персонаж не влияет на симметрию, он просто расширяет середину. Для этого вы должны держать дополнительный указатель, который отслеживает, где лежит край плато (середины). Например, у вас есть (b) baabb, и вы только что получили другое «b», в этом случае вы должны знать, чтобы сбросить указатель на основание среднего плато здесь: bbaa (b) bb. Так как мы идем на постоянное время, вы должны держать указатель здесь для начала (вы не можете позволить себе время для поиска края плато). Теперь, если вы получили еще один «b», вы знаете, что вы все еще на краю этого плато, и вы удерживаете указатель там, где он находится, поэтому bbaa (b) bb -> bbaa (b) bbb. Теперь, если вы получаете «a», вы знаете, что «b» не являются частью расширенной середины, и вы сбрасываете оба указателя (указатель отслеживания и указатель края), так что теперь у вас есть bbaabbbb ((a)).
В этих трех случаях я думаю, что все базы покрыты. Если вы когда-нибудь захотите проверить, является ли текущая строка палиндромом, проверьте, имеет ли первый указатель (не указатель края плато) индекс 0.