LeetCode 最短回文子串

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

示例 1:

输入: "aacecaaa"
输出: "aaacecaaa"

示例 2:

输入: "abcd"
输出: "dcbabcd"

思路分析:首先我们需要确定最短的回文中心在哪里。

回文中心分两种情况:(我们从正中间向右扫描,穷举回文中心)
	1、形如  "abbacd" 这种,中心为两个字符,中心下标为1、2两个(特殊情况为“aabcd”中心下标为0,1)
	2、形如  "aacecaaa" ,中心为一个字符串,中心下标为3(特殊情况为“abced”中心为下标0)

找到中心后,我们将对称部分后面的字符串截出,然后反转,最后加上原字符串就是最短的回文字符串。

class Solution {
public:
    string shortestPalindrome(string s) {
        int sSize = s.size();
        if (sSize < 2){
            return s;
        }
        int beginIndex, endIndex;
        string result;
        int midIndex = sSize / 2 - 1 + sSize % 2;//计算这个字符串的中心
        //对中心进行穷举
        while (midIndex >= 0){
            //对于两个中心的情况
            if (s[midIndex] == s[midIndex + 1] && isTrueMid(s, midIndex - 1, midIndex + 2)){
                result = s.substr(midIndex * 2 + 2, sSize);//截出后面剩余的部分
                break;
            }
            //对于一个中心的特殊情况
            if (midIndex == 0){
                result = s.substr(midIndex + 1, sSize);
                break;
            }
            //对于一个中心的一般情况
            if (isTrueMid(s, midIndex - 1, midIndex + 1)){
                result = s.substr(midIndex * 2 + 1, sSize);
                break;
            }
            midIndex -= 1;
        }
        reverse(result.begin(), result.end());//反转
        result += s;//加上原字符串就是最短的回文字符串
        return result;
    }
    //判断beginIndex和endIndex两个是否相等,即中心是否有效
    bool isTrueMid(string &s, int beginIndex, int endIndex){
        while (beginIndex >= 0 && s[beginIndex] == s[endIndex]){
        		beginIndex -= 1;
        		endIndex += 1;
        }
        return beginIndex == -1;
    }
};

LeetCode 最短回文子串_第1张图片
方法二:首先将s的反转与s拼接,然后去掉中间对称的部分即可。

class Solution {
public:
    string shortestPalindrome(string s) {
        string rs = s;
        reverse(rs.begin(), rs.end());//反转
        string m = s + "#" + rs;//反转与原字符串拼接
        vector next(m.size(), 0);
        for(int j = 1, k = 0; j < m.size(); j++)
        {
            while(k > 0 && m[j] != m[k])
                k = next[k - 1];
            if(m[j] == m[k])
                k++;
            next[j] = k;
        }
        
        int pos = next[m.size() - 1];
        int len = rs.size() - pos;
        return rs.substr(0, len) + s;
    }
};

你可能感兴趣的:(LeetCode)