給定一個字符串 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; }