曾经有一个好算法放到我面前,我没有好好珍惜,直到用到的时候才后悔莫及。
那就是Manacher(马拉车算法),以O(n)的复杂度计算最长回文字符串。
曾经刷Leetcode的时候,室友跟我说了这个算法,但当时那个题目用中间枚举也过了,我就没有在意,直到前天才弄会,写这篇报告之前,
我又专门写了一遍马拉车,果然还是有点问题的。
详细原理链接 点击 Mark
#include <stdio.h> #include <iostream> #include <string.h> using namespace std; const int N = 1e6 + 50; char str[N]; char sstr[N*2]; int rad[N*2]; int manacher(char str[], int rad[]) { int n = strlen(str); int j = 0, k,ans = 0; for(int i = 0; i < n; i += k) { while(i-j>=0 && i+j<n && str[i-j] == str[i+j]) j++; rad[i] = --j; for(k = 1; k <= rad[i] && rad[i-k] != rad[i]-k; k++) { rad[i+k] = min(rad[i-k], rad[i]-k); } j = max(j-k, 0); } for(int i = 0; i < n; i++) ans = max(ans, rad[i]); return ans; } int main() { int kase = 0; while(scanf("%s", str) != EOF) { if(strcmp(str, "END") == 0) break; int n = strlen(str); for(int i = 0; i < n; i++) { sstr[i*2] = ‘#‘; sstr[i*2+1] = str[i]; } sstr[2*n] = ‘#‘; sstr[2*n+1] = ‘\0‘; memset(rad, 0, sizeof(rad)); int ans=manacher(sstr, rad); printf("Case %d: %d\n", ++kase, ans); } return 0; }
时间: 2024-11-05 12:08:53