mirror of
https://github.com/youngyangyang04/leetcode-master.git
synced 2025-07-06 15:09:40 +08:00
Merge pull request #2757 from huanxiangxingyun/master
0005.最长回文子串 Manacher算法C++版本
This commit is contained in:
@ -256,7 +256,60 @@ public:
|
||||
* 时间复杂度:O(n^2)
|
||||
* 空间复杂度:O(1)
|
||||
|
||||
### Manacher 算法
|
||||
|
||||
Manacher 算法的关键在于高效利用回文的对称性,通过插入分隔符和维护中心、边界等信息,在线性时间内找到最长回文子串。这种方法避免了重复计算,是处理回文问题的最优解。
|
||||
|
||||
```c++
|
||||
//Manacher 算法
|
||||
class Solution {
|
||||
public:
|
||||
string longestPalindrome(string s) {
|
||||
// 预处理字符串,在每个字符之间插入 '#'
|
||||
string t = "#";
|
||||
for (char c : s) {
|
||||
t += c; // 添加字符
|
||||
t += '#';// 添加分隔符
|
||||
}
|
||||
int n = t.size();// 新字符串的长度
|
||||
vector<int> p(n, 0);// p[i] 表示以 t[i] 为中心的回文半径
|
||||
int center = 0, right = 0;// 当前回文的中心和右边界
|
||||
|
||||
|
||||
// 遍历预处理后的字符串
|
||||
for (int i = 0; i < n; i++) {
|
||||
// 如果当前索引在右边界内,利用对称性初始化 p[i]
|
||||
if (i < right) {
|
||||
p[i] = min(right - i, p[2 * center - i]);
|
||||
}
|
||||
// 尝试扩展回文
|
||||
while (i - p[i] - 1 >= 0 && i + p[i] + 1 < n && t[i - p[i] - 1] == t[i + p[i] + 1]) {
|
||||
p[i]++;// 增加回文半径
|
||||
}
|
||||
// 如果当前回文扩展超出右边界,更新中心和右边界
|
||||
if (i + p[i] > right) {
|
||||
center = i;// 更新中心
|
||||
right = i + p[i];// 更新右边界
|
||||
}
|
||||
}
|
||||
// 找到最大回文半径和对应的中心
|
||||
int maxLen = 0, centerIndex = 0;
|
||||
for (int i = 0; i < n; i++) {
|
||||
if (p[i] > maxLen) {
|
||||
maxLen = p[i];// 更新最大回文长度
|
||||
centerIndex = i;// 更新中心索引
|
||||
}
|
||||
}
|
||||
// 计算原字符串中回文子串的起始位置并返回
|
||||
return s.substr((centerIndex - maxLen) / 2, maxLen);
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
|
||||
|
||||
* 时间复杂度:O(n)
|
||||
* 空间复杂度:O(n)
|
||||
|
||||
## 其他语言版本
|
||||
|
||||
@ -682,3 +735,4 @@ public class Solution {
|
||||
<a href="https://programmercarl.com/other/kstar.html" target="_blank">
|
||||
<img src="../pics/网站星球宣传海报.jpg" width="1000"/>
|
||||
</a>
|
||||
|
||||
|
Reference in New Issue
Block a user