马拉车(Manacher)算法(具体算法流程看这个哥们的:https://blog.csdn.net/qq_35065720/article/details/104205920):
算法解决:在一个字符串中找到最长的回文字符串。
实现策略:
以每个位置作为中心,向两边扩展,可以确定奇回文,但是偶回文无法这样做。
解决方法:在字符串中间及两边插入某种字符,此时可以按照这种方法进行扩展。此时无论奇回文还是偶回文都可以找到。
例如11211,此时添加任意字符在两边#1#1#2#1#1#此时均可以进行回文判断。
C++代码实现:
class Solution1 { public: char* manacherString(string str) { char* charArr = new char[str.size() * 2 + 1]; int str_len = str.size(); for (int i = 1; i <= str_len; i++) { charArr[2 * i] = str[i - 1]; charArr[2 * i + 1] = ‘#‘; } return charArr; } int maxLcpsLength(string str) { if (str.size() == 0) { return 0; } char* charArr = manacherString(str); vector<int> pArr(strlen(charArr)); // 回文半径数组 int C = -1; int R = -1; int max_val = INT_MIN; for (int i = 0; i != strlen(charArr); i++) { pArr[i] = R > i ? min(pArr[2 * C - i], R - i) : 1; // R > i 表示 i在回文右边界里面,有一个不用验的区域 // 2*C-i 为 i关于C的对称点i‘,两个瓶颈:1.i‘的回文半径 2. R到我(i)的距离 while (i + pArr[i] < strlen(charArr) && i - pArr[i] > -1) { // 左右两边都不越界 if (charArr[i + pArr[i]] == charArr[i - pArr[i]]) { // 在不用验的区域下再扩一下 pArr[i]++; } else { break; } } if (i + pArr[i] > R) { R = i + pArr[i]; // 更新右边界 C = i; // 更新中心位置 } max_val = max(max_val, pArr[i]); // 全局最大值 } return max_val - 1; } };
原文地址:https://www.cnblogs.com/E-Dreamer-Blogs/p/12642756.html
时间: 2024-11-09 02:54:00