理解最短回文
最短回文串
给定一个字符串 s,你可以通过在字符串前面添加字符将其转换为回文串。找到并返回可以用这种方式转换的最短回文串
示例1
输入: "aacecaaa"
输出: "aaacecaaa"
示例2
输入: "abcd"
输出: "dcbabcd"
找到从头开始的最长回文串s[:i],在头上加上s[i:]的翻转即可
class Solution(object):
def shortestPalindrome(self, s):
"""
:type s: str
:rtype: str
"""
r = s[::-1]
for i in range(len(s) + 1):
if s.startswith(r[i:]):
return r[:i] + s
1. len(s)+1是为了匹配到空字符串这种特殊情况;
2. startswith要完整的子串与S匹配;
3. 为什么return r[:i] + s,因为r是颠倒过来的字符串,为什么要这样写呢?理由如下:
假设我们的字符串是"abdea",我们可以在前面加个逆序之后的字符串即为:"aedba|abdea",是不是很接近最短回文了,虽然它还不满足回文,但是已经可以从中间往两边走了,有回文的那个味道了,但是怎么样才能满足呢? 它一定满足
S
逆
序
+
S
中
间
+
S
正
序
S_{逆序}+S_{中间}+S_{正序}
S逆序+S中间+S正序这种形式,其中
S
中
间
S_{中间}
S中间是由两个相同子串组成,那么我们找到这个相同子串并删除其中一个子串就得到回文了。"aedbaabdea"相同子串为"aa"那么我们删除其中一个不就得到了回文"aedbaabdea"。再举一个例子 "aacecaaa",加逆序之后"aaacecaa|aacecaaa"相同子串"aacecaa",删除之后得到回文"aaacecaaa"。
为什么那么中间的部分如何保证回文呢,很简单,因为这一部分和逆序的部分已经相同,而且是逆序[i:]和正序[:i]相同,只有一种可能这一部分本身就是回文了。