最短回文串

题目描述

给定一个字符串 s,你可以通过在字符串前面添加字符将其转换为回文串。找到并返回可以用这种方式转换的最短回文串。

示例 1:
输入: “aacecaaa”
输出: “aaacecaaa”

示例 2:
输入: “abcd”
输出: “dcbabcd”

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/shortest-palindrome
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

思路一(超时)

创建原字符串的翻转rev,迭代寻找原字符串s中以s[0]为首元素的最长的回文串,将剩余元素翻转添加到s之前即可。

代码(c++)

class Solution {
public:
    string shortestPalindrome(string s) {
        string res;
        if(s.length()==0) return res;
        string rev=s;
        reverse(rev.begin(),rev.end());
        for(int i=0;i<s.length();i++){
            if(s.substr(0,s.length()-i)==rev.substr(i)){
                return rev.substr(0,i)+s;
            }
        }
        return res;
    }
};

思路二(KMP算法)

KMP算法中的next数组记录的值不仅是如果当前字符失配,下一个要与该失配字符进行匹配的模式串中的字符。同时也是模式串中除当前字符外的最长相同前后缀,如下图所示。
在这里插入图片描述
next数组最后一个字符D对应的值为2,说明以其前字符为尾的最长相等前后缀长度为2,即ABCDAB
于是可以想到,将原字符串s及其翻转rev拼接在一起,将其看做模式串求next数组,求出最后一个字符的最长相等前后缀的长度,就是以s[0]为首元素的最长回文串的长度。
如s=bcba,则rev=abcb,拼接后为bcbaabcb,最长相等前后缀就是bcb(bcbaabcb),则将剩余元素a添加到s之前,便可得最短回文串。
注意:
1、将原字符串s及其翻转rev拼接时,要在其间添加一个非字母字符(如“#”)。如果没有“#”,两个字符串可能会发生混淆,比如“aaaa”,如果不在中间插入“#”,新字符串会是“aaaaaaaa”, 最长前缀大小会成为 7,这显然是错的。因此,中间的分隔符是必要的。
2、因为next的值是除当前字符外的最长相同前后缀的长度,所以对于最后一个元素s[n-1],要判断s[next[n-1]]与s[n-1]是否相同,如果相同则以s[0]为首元素的最长回文串的长度为next[n-1]+1,否则为1(s[0]本身)。

代码(c++)

class Solution {
public:
    vector<int> getNext(string s,int len){
        vector<int> next;
        int j=-1;
        next.push_back(-1);
        for(int i=1;i<len;i++){
            while(j!=-1&&s[i]!=s[j+1]){
                j=next[j];
            }
            if(s[i]==s[j+1]){
                j+=1;
            }
            next.push_back(j);
        }
        return next;
    }
    string shortestPalindrome(string s) {
        string res;
        if(s.length()==0) return res;
        string rev=s;
        reverse(rev.begin(),rev.end());
        string temp=s+"#"+rev;
        vector<int> next=getNext(temp,temp.size());
        int longestEqual=temp[next[temp.size()-1]]==temp[temp.size()-1]?next[temp.size()-1]+1:0;
        return rev.substr(0,rev.size()-longestEqual)+s;
    }
};

你可能感兴趣的:(LeetCode)