一、暴力破解
#include <stdbool.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
// 判断字符串是否是回文字符串
int isPalindromic(char *str, int start, int end)
{
while (start < end)
{
if (str[start] != str[end])
{
return false;
}
start++;
end--;
}
return true;
}
char *longestPalindrome(char *str)
{
int len = strlen(str);
int k = 0;
if (len < 2)
{
return str;
}
// 回文字符串最小长度为1,因为任何一个字符从左往右和从右往左读都是回文的
// 因此长度为1的子串是回文的,默认返回第一个字符
int maxLen = 1, startIndex = 0;
// 遍历所有长度>=2的子串,如果没有,则使用上面的默认值,即
// 返回长度为1的子串,并且是字符串第一个字符
for (int i = 0; i < len - 1; i++)
{
for (int j = i + 1; j < len; j++)
{
// 当新的子串长度大于maxLen时,再判断是否回文
// 如果回文,则更新maxLen,同时更新startIndex
if (j - i + 1 > maxLen && isPalindromic(str, i, j))
{
maxLen = j - i + 1;
startIndex = i;
}
}
}
// 下面这两行代码这样可以将空间复杂度降到O(1)
// str[startIndex + maxLen] = '\0';
// return str + startIndex;
// 分配存储空间,存储新字符串并返回
// 分配的时候要多分配一个空间用来存储空字符'\0'
char *palindromic = (char *)malloc((maxLen + 1) * sizeof(char));
for (int i = 0; i < maxLen; i++)
{
palindromic[i] = str[startIndex + i];
}
palindromic[maxLen] = '\0';
return palindromic;
}
int main(void)
{
int i = 0;
char str[] = "babad";
char *palind = NULL;
palind = longestPalindrome(str);
while (palind[i] != '\0')
{
printf("%c", palind[i]);
i++;
}
}
执行用时:304 ms, 在所有 C 提交中击败了26.13%的用户
内存消耗:5.9 MB, 在所有 C 提交中击败了79.53%的用户
时间复杂度O(n^3),空间复杂度O(n)。
这种方法只会返回一种解,即可能有多个最长回文串,此方法只返回最先遍历到的。
中心扩散法
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
// 中心扩散法
int expandCenter(char *str, int left, int right, int len)
{
// 如果长度是奇数,则中心只有一个,left和right传相同的值
// 如果长度是偶数,则中心是两个数,left和right相差1
while (left >= 0 && right < len)
{
if (str[left] == str[right])
{
left--;
right++;
}
else
{
break;
}
}
return right - left - 1;
}
char *longestPalindrome(char *str)
{
int len = strlen(str);
if (len < 2)
{
return str;
}
int maxLen = 1;
int startIndex = 0;
for (int i = 0; i < len; i++)
{
// 当回文串长度为奇数时调用
int odd = expandCenter(str, i, i, len);
// 当回文串长度为偶数时调用
int even = expandCenter(str, i, i + 1, len);
// 将最长的赋值给maxLen
int newMaxLen = odd > even ? odd : even;
if (newMaxLen > maxLen)
{
maxLen = newMaxLen;
startIndex = i - (maxLen - 1) / 2;
}
}
// 下面这两行代码这样可以将空间复杂度降到O(1)
// str[startIndex + maxLen] = '\0';
// return str + startIndex;
char *palindromic = (char *)malloc((maxLen + 1) * sizeof(char));
for (int i = 0; i < maxLen; i++) {
palindromic[i] = str[i + startIndex];
}
palindromic[maxLen] = '\0';
return palindromic;
}
int main(void)
{
char str[] = "abcdefghgfedklmn";
char *palind = longestPalindrome(str);
int i = 0;
while (palind[i] != '\0') {
printf("%c", palind[i]);
i++;
}
}
执行用时:20 ms, 在所有 C 提交中击败了80.27%的用户
内存消耗:6 MB, 在所有 C 提交中击败了68.40%的用户
时间复杂度O(n^2),空间复杂度O(n)。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。