给定一个字符串 s,你可以通过在字符串前面添加字符将其转换为回文串。找到并返回可以用这种方式转换的最短回文串。
示例 1:
输入:s = "aacecaaa" 输出:"aaacecaaa"
示例 2:
输入:s = "abcd" 输出:"dcbabcd"
>>关于KMP 算法 和 核心 j = D[j-1] 可以看一下我的往期文章:
KMP substring search 算法 案例分析-CSDN博客https://blog.csdn.net/weixin_41987016/article/details/133908991?spm=1001.2014.3001.5501KMP 算法 + 详细笔记 + 核心分析 j = D[j-1]-CSDN博客https://blog.csdn.net/weixin_41987016/article/details/133848188?spm=1001.2014.3001.5501>>KMP 解法
发现 s 最长前缀是回文的,它翻转之后的 rev_s 的最长后缀也是回文的,且 s 的最长回文前缀和res_s 的最长回文后缀是相等。(这是因为回文串经过翻转还是本身)
于是拼接:temp_s = s + '#' + rev_s = "haha#ahah",可以发现 temp_s的最长公共前后缀 正是其s 的最长回文前缀 和 res_s 的最长回文后缀。因为rev_s去掉最长回文后缀,剩余的与s拼接也就可以获得最短的回文串。那也就是rev_s去掉最长公共前后缀,剩余的与s拼接也就可以获得最短的回文串。
- 1.翻转字符串:rev_s
- 2.拼接:temp_s=s+'#'+rev_s
- 3.求串temp_s的最长公共前后缀
- 4.rev_s“砍去”最长公共前后缀,剩余的rev_s + s 为所求
class Solution {
public:// D[i]:D[0]~D[i] 共有 i+1 个字符的最大公共前后缀void getD(int D[],string pattern){int i=1,j=0;int np = pattern.size();while(i < np) {if(pattern[i] == pattern[j]) {D[i] = ++j;i++;// 可简写D[i++] = ++j;}else{if(j>0) j=D[j-1];else i++;}}}string shortestPalindrome(string s) {string rev_s = s;reverse(rev_s.begin(), rev_s.end());string temp_s = s + '#' + rev_s;int n = temp_s.size();int *D = new int [n]();getD(D,temp_s);return rev_s.substr(0,rev_s.size()-D[n-1]) + s.substr(0, s.size());}
};
参考和推荐文章:
214. 最短回文串 - 力扣(LeetCode)https://leetcode.cn/problems/shortest-palindrome/solutions/392676/shou-hua-tu-jie-cong-jian-dan-de-bao-li-fa-xiang-d/