Leetcode5最长回文子串
5最长回文子串
给定一个字符串 s,找到 s 中最长的回文子串。你可以假设 s 的最大长度为 1000。
示例 1:
输入: "babad"
输出: "bab"
注意: "aba" 也是一个有效答案。
示例 2:
输入: "cbbd"
输出: "bb"
来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/longest-palindromic-substring 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
Solution 1
中心扩展算法
思路:根据回文字符串的对称性求解
时间复杂度:O(n2)
执行用时:16 ms
内存消耗:5.5 MB
void expandOdd(char *s, int s_len, int mid, int *l, int *r);
void expandEven(char *s, int s_len, int mid, int *l, int *r);
char *longestPalindrome(char *s)
{
int start = 0, end = 0, mid = 0, left = 0, right = 0;
int s_len = strlen(s);
for (mid = 0; mid < s_len; mid++)
{
expandOdd(s, s_len, mid, &left, &right);
if (right - left > end - start)
{
start = left;
end = right;
}
expandEven(s, s_len, mid, &left, &right);
if (right - left > end - start)
{
start = left;
end = right;
}
}
if (s_len > 0)
s[end + 1] = '\0';
return &s[start];
}
void expandOdd(char *s, int s_len, int mid, int *left, int *right)
{
int l = mid - 1;
int r = mid + 1;
while (0 <= l && r <= s_len && s[l] == s[r])
{
l--;
r++;
}
l++;
r--;
*left = l;
*right = r;
}
void expandEven(char *s, int s_len, int mid, int *left, int *right)
{
int l = mid;
int r = mid + 1;
while (0 <= l && r <= s_len && s[l] == s[r])
{
l--;
r++;
}
l++;
r--;
*left = l;
*right = r;
}
Solution 2
Manacher算法
时间复杂度:O(n)
执行用时:4 ms
内存消耗:6.3 MB
char *longestPalindrome(char *s)
{
int s_len = strlen(s);
int str_len = s_len * 2 + 1;
char *str = (char *)malloc(str_len * sizeof(char));
int *arr = (int *)malloc(str_len * sizeof(int));
int mid = 0;
int i = 0, l = 0, r = 0;
int max_r = 0, center = 0;
int max_pos = 0;
for (i = 0; i < str_len; i++)
{
if (i % 2 == 0)
str[i] = '#';
else
str[i] = s[i / 2];
}
for (mid = 0; mid < str_len; mid++)
{
if (2 * center - mid <= 0 || max_r - mid <= 0)
arr[mid] = 0;
else if (arr[2 * center - mid] < max_r - mid)
arr[mid] = arr[2 * center - mid];
else
arr[mid] = max_r - mid;
l = mid - arr[mid];
r = mid + arr[mid];
while (0 <= l && r < str_len && str[l] == str[r])
{
l--;
r++;
}
l++;
r--;
arr[mid] = (r - l) / 2;
if (arr[max_pos] < arr[mid])
max_pos = mid;
if (r > max_r)
{
max_r = r;
center = mid;
}
}
if (s_len > 0)
s[max_pos / 2 + (arr[max_pos] + 1) / 2] = '\0';
return &s[max_pos / 2 - arr[max_pos] / 2];
}