[LeetCode] Longest Palindromic Substring
题目
https://leetcode.com/problems/longest-palindromic-substring/
Given a string s, find the longest palindromic substring in s. You may assume that the maximum length of s is 1000.
Example:
Input: "babad"
Output: "bab"
Note: "aba" is also a valid answer.
Example:
Input: "cbbd"
Output: "bb"
思路
采用Manacher算法。
参考:
[转载] Manacher 算法
这两篇文章结合着看,就可以弄明白Manacher算法的意思了。
代码
94 / 94 test cases passed.
Runtime: 3 ms
#define MAX 1000
#define min(a,b) ((a)<(b)?(a):(b))
int manacher(char *s, char output[]) {
int i = 0;
char s2[MAX*2+10] = {0};
s2[0] = '$';
for (; s[i] != '\0'; i++) {
s2[(i<<1)+1] = '#';
s2[(i<<1)+2] = s[i];
}
s2[(i<<1)+1] = '#';
int len = (i<<1)+2;
s2[len] = '\0';
int p[MAX*2+10] = {0}; // 以s2中某一点为中心的回文半径
int id = 0; // 回文的中心点
int limit = 0; // 最长回文的右边界点
int maxLen = 0; // 最大回文长度
int maxId = 0; // 最长回文的中心点
for (i = 1; i < len; i++) {
if (i < limit) {
p[i] = min(p[2*id-i], limit-i);
} else {
p[i] = 1;
}
while (s2[i+p[i]] == s2[i-p[i]]) {
p[i]++;
}
if (i+p[i] > limit) {
limit = i+p[i];
id = i;
}
if (maxLen < p[i]-1) {
maxLen = p[i]-1;
maxId = i;
}
}
//printf("maxId: %d, maxLen: %d\n", maxId, maxLen);
int j = 0;
// maxLen = p[maxId]-1, 从 maxId-(p[maxId]-1)到maxId+(p[maxId]-1)是带有#的最长回文,将#号去掉
// maxId-(p[maxId]-1)到maxId+(p[maxId]-1) 可以简化为 maxId-maxLen到maxId+maxLen
for (i = maxId - maxLen; i <= maxId+maxLen; i++) {
//printf("%c", s2[i]);
if (s2[i] != '#') {
output[j++] = s2[i];
}
}
return maxLen;
}
char* longestPalindrome(char* s) {
if (s == NULL) return "";
if (s[0] == '\0') return "";
char *output = (char*) malloc(MAX+10);
int maxLen = 0;
maxLen = manacher(s, output);
output[maxLen] = '\0';
return output;
}