给定一个字符串 s,你能够经过在字符串前面添加字符将其转换为回文串。找到并返回能够用这种方式转换的最短回文串。python
示例 1:ios
输入: "aacecaaa" 输出: "aaacecaaa"
示例 2:c++
输入: "abcd" 输出: "dcbabcd"
直觉告诉咱们,咱们找出左边的最长回文子串,好比aacecaaa
左侧最长的回文子串就是aacecaa
,而后将右侧剩余的部分反转补到原串的左侧便可。因为找的是最长的回文子串,直接从右往左,找到第一个回文子串便可。对应的代码以下所示数组
class Solution: def shortestPalindrome(self, s): """ :type s: str :rtype: str """ r = 1 for i in range(len(s), 0, -1): if s[0:i] == (s[0:i])[::-1]: r = i break return (s[r:])[::-1] + s
第二种思路相较于第一种思路更为巧妙,利用到了KMP中的fail数组,也有人叫作next数组。spa
由于fail数组中记录了最短回退位置,也即保证了回退后所匹配的部分是最长的。咱们直接将原串和反转的原串拼在一块儿,求出其fail数组,最后的位置可以回退到的位置即为左侧最长的回文子串。code
#include<bits/stdc++.h> using namespace std; static auto x = []() { std::ios::sync_with_stdio(false); std::cin.tie(NULL); return 0; } (); const int maxn = 100010; int fail[maxn]; class Solution { public: string shortestPalindrome(string s) { string t(s); reverse(t.begin(), t.end()); string st = s + "#" + t; int sz = st.size(); for(int i = 0,j = fail[0] = -1; i < sz; ++i) { while(j != -1 && st[i] != st[j]) j = fail[j]; fail[i + 1] = ++j; if(st[i + 1] == st[j]) fail[i+1] = fail[j]; } return t.substr(0, t.size()-fail[sz]) + s; } }; int main() { return 0; }