Given a string s, you are allowed to convert it to a palindrome by adding characters in front of it. Find and return the shortest palindrome you can find by performing this transformation.
Example 1:
Input:"aacecaaa"
Output:"aaacecaaa"
Example 2:
Input:"abcd"
Output:"dcbabcd"
给定一个字符串 s,你可以通过在字符串前面添加字符将其转换为回文串。找到并返回可以用这种方式转换的最短回文串。
示例 1:
输入: "aacecaaa"
输出: "aaacecaaa"
示例 2:
输入: "abcd"
输出: "dcbabcd"
解题思路:
解法一:求从0开始的最大回文串,假设(0 , i)是最大回文串,则将s.substr(i)翻转后作为前缀加入s中。
但是在判断是否最大回文串这里耗的时间是O(N),如果遍历i的话总的时间复杂度是O(N^2) ;所以会TLE 。 就说明自己天真啊。。。
解法一:
class Solution {
public:
string shortestPalindrome(string s)
{
if(s.empty()) return "" ;
int len = s.size() ;
int right = 0 ;
int maxl = 0 ;
string ans ;
for(int i = 1 ; i < len ; ++i)
{
if(ispalin(s.substr(0 , i + 1)))
{
maxl = max(maxl , i) ;
}
}
string sub = s.substr(maxl + 1) ;
reverse(sub.begin() , sub.end()) ;
ans += sub + s ;
return ans ;
}
bool ispalin(string s)
{
if(s.empty()) return true ;
string w = s ;
reverse(w.begin() , w.end()) ;
return s == w ;
}
};
解法二:
后来看了[LeetCode] 214. Shortest Palindrome 最短回文串--grandyang的博客
通过双指针来做,确实是非常巧妙的方法,目的是为了找回文串的中间位置,然后从中间位置向两边比较。这样(0 , i)是可能的最长回文字符子串,但不一定是;但是可以判断[i , len)一定不是。所以将[ i , len )翻转后作为s的前缀 ,递归求解[0 , i) .
for(int j = len - 1 ; j >= 0 ; --j)
{
if(s[i] == s[j]) ++i ;
}
解法二:
class Solution {
public:
string shortestPalindrome(string s) {
int i = 0 , len = s.size() ;
for(int j = len - 1 ; j >= 0 ; --j)
{
if(s[i] == s[j]) ++i ;
else break ;
}
if(i == len) return s ;
i = 0 ;
for(int j = len - 1 ; j >= 0 ; --j)
{
if(s[i] == s[j]) ++i ;
}
string sub = s.substr(i) ;
reverse(sub.begin() , sub.end()) ;
return sub + shortestPalindrome(s.substr(0 , i)) + s.substr(i) ;
}
};