【LeetCode】214. 最短回文串 结题报告 (C++)

原题地址:https://leetcode-cn.com/problems/shortest-palindrome/

题目描述:

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

示例 1:

输入: "aacecaaa"
输出: "aaacecaaa"
示例 2:

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

 

解题方案:

本题核心思想是采用KMP算法,参考地址:https://segmentfault.com/a/1190000003797346

大学本科就学过KMP算法,算法比较知名,一直还没怎么弄懂。。。。

字符串的处理方式也是很巧妙的,首先得到最长的回文串,然后再采用KMP算法进行删减。

代码:

class Solution {
public:
    string shortestPalindrome(string s) {
        // 将字符串反转后拼接到后面
        string rev(s);
        reverse(rev.begin(), rev.end());;
        string combine = s + "#" + rev;
        
        // 计算LPS表值
        vector lps(combine.length(), 0);
        int remove = getLPS(combine, lps);
        
        // 去掉后缀后,将反转字符串拼回前面
        string prepend = rev.substr(0, rev.length() - remove);
        return prepend + s;
    }
    
    int getLPS(string s, vector& lps){
        // i是后缀末尾的指针,j是前缀末尾的指针
        int j = 0, i = 1;
        // 从j=0,i=1开始找,错开了一位
        while(i < s.length()){
            // 如果字母相等,则继续匹配,最长相同前后缀的长度也加1
            if(s[i] == s[j]){
                lps[i] = j + 1;
                i ++;
                j ++;
            // 如果不同
            } else {
                // 如果前缀末尾指针还没退回0点,则找上一个子前缀的末尾位置
                if(j != 0){
                    j = lps[j - 1];
                // 如果退回0点,则最长相同前后缀的长度就是0了
                } else {
                    lps[i] = 0;
                    i ++;
                }
            }
        }
        return lps[lps.size() - 1];
    }
};

 

你可能感兴趣的:(【LeetCode】214. 最短回文串 结题报告 (C++))