leetcode 214. Shortest Palindrome
这道题的意思是往字符串前面添加字串,使得整个字符串是回文串;
第一种方法:
既然是回文串,那么最先想到的是最长回文子串。最长回文子串的pat是pat[index] 代表以index为中点左右两边最长的回文串。
那么如果pat[index] == index说明从起始点到该点再加上index是回文串的。那么我们只要找到这样的一个最大的pat[index]即可。
class Solution { public: string shortestPalindrome(string s) { if (s.length() <= 1) return s; string ss = initS(s); vector<int> pat = initCalc(ss); int min_len = s.length() - 1; for (int i = 1; i < (ss.length()+1)/2; ++i) { if (pat[i] == i) { int len = (ss.length() - i * 2 - 1) / 2; min_len = min_len < len?min_len : len; } } string result; for (int i = 0; i < min_len; ++i) { result.push_back(s[s.length() - i - 1]); } result += s; return result; } string initS(const string& s) { string result(s.length() * 2 + 1, '#'); for (int i = 0; i < s.length(); ++i) result[i * 2 + 1] = s[i]; return result; } vector<int> initCalc(const string& ss) { vector<int> result(ss.length(), 0); int max_right = 0; int max_middle = 0; for (int i = 1; i < ss.length(); ++i) { if (i < max_right) { int left_pos = max_middle * 2 - i; result[i] = result[left_pos]; if (result[i] + i > max_right) result[i] = max_right - i; } int pos = i + result[i] + 1; while (pos < ss.length() && pos <= i * 2 && ss[pos] == ss[i*2-pos]) ++pos; result[i] = pos - i - 1; if (pos - 1 > max_right) { max_right = pos - 1; max_middle = i; } } return result; } };
如上先求出pat,然后再找最长子串。
第二种方法:
既然是子串,并且是从最开始的字符串开始匹配的。那么跟kmp里面的计算next很相似:next是计算跟起始字符相同的子串的长度。比如:abc.....abc; next= 000......123
那么我们如果有这么一个字符串:abc,我们将它构造成 abc#cba 那么next.back()的长度就是从a开始的最长回文子串;
所以计算的过程即为求next的过程。
string shortestPalindrome(string s) { if(s.size()<=1) return s; string r = s; reverse(r.begin(), r.end()); r = s + "#" + r; vector<int> next(r.length(), 0); for (int i = 1; i < next.size(); ++i) { int j = next[i-1]; while (j > 0 && r[j] != r[i]) j = next[j-1]; next[i] = j + (r[i] == r[j]?1:0); } string temp = s.substr(next.back()); reverse(temp.begin(), temp.end()); return temp + s; }
如上两种算法的效率差不多都是一样的O(n),但是第二种算法的计算过程比第一种算法简单的多。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!