给定一个字符串 s,你可以通过在字符串前面添加字符将其转换为回文串。找到并返回可以用这种方式转换的最短回文串。
示例 1:
输入: "aacecaaa"
输出: "aaacecaaa"
示例 2:
输入: "abcd"
输出: "dcbabcd"
这题非常难,如果是用暴力是很简单的,但是时间复杂度不过关,要用到KMP的知识点,从头开始学是很难理解的,花了几个小时才弄明白。
首先看这道题,添加字符串使其为回文串,其实分析来分析去,这道题就是求前面的最长回文串。
aacecaaa为例子,前面的最长回文串是aacecaa,因此只要加个a即可。
暴力法求出来最长回文串是很简单的,但是会超时。
因此用KMP方法,所谓的KMP就是KMP算法是一种改进的字符串匹配。
我们这里建一个要求的s的字符串逆序来连接到s后面。
aacecaaa aaacecaa 熟悉KMP算法的都知道next的最后一位存储的就是当前的前后缀最长匹配长度。因此答案就出来了
注意:在逆序和正序中间应该加一个分隔字符,使得前缀一定在正序结束。
class Solution {
public:
string shortestPalindrome(string s) {
int n=s.size();
string rev(s);
reverse(rev.begin(),rev.end());
string new_s=s+"#"+rev;
int new_n=new_s.size();
vector<int> next(new_n, 0);
next[0]=0;
for(int i=1,t=0;i<new_n;i++){
while(t>0 && new_s[i]!=new_s[t]) t=next[t-1];
if(new_s[i]==new_s[t]) t++;
next[i]=t;
}
string ans=rev.substr(0,n-next[new_n-1])+s;
return ans;
}
};
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/shortest-palindrome
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
网友评论