5. 最长回文子串
给定一个字符串 s,找到 s 中最长的回文子串。你可以假设 s 的最大长度为 1000。
示例 1:
输入: “babad”
输出: “bab”
注意: “aba” 也是一个有效答案。
示例 2:
输入: “cbbd”
输出: “bb”
来源:力扣(LeetCode) 5. 最长回文子串
链接:https://leetcode-cn.com/problems/longest-palindromic-substring
法一:暴力法(执行时间252 ms)
遍历所有可能的子串搭配,在判断该子串是否为回文串。在所有满足要求的子串中记录最长的一串子串。
static bool IsPalindromic(char *str, int len)//用于判断子串是否为回文串
{
for(int i = 0, j = len -1; i < j; i++,j--)
{
if(str[i] != str[j])
{
return false;
}
}
return true;
}
char * longestPalindrome(char * s)
{
int len = strlen(s);
if(s == NULL) return NULL;
int max = 0; //记录子串长度
char* maxVal = (char*)malloc(len+1); //记录子串
memset(maxVal, 0 ,len+1);
for(int i = 0; len-i > max; i++)
{
for(int j = i+1; j <= len; j++)
{
if(j-i > max && IsPalindromic(s+i, j-i))
{
max = j-i;
//strcpy_s(maxVal, j-i, s+i);
strcpy(maxVal, s+i);
maxVal[j-i] = '\0';
}
}
}
return maxVal;
}
法二:(来源于力扣、执行时间8ms)
此方法来源与力扣的解题,内容稍作修改。解题思路为,先找到一个可能成为新子串的中心位置,从中心位置向两边查找回文。
!
char* longestPalindrome(char* str)
{
int length = strlen(str);
char* result = (char*)malloc(length + 1);
assert(result != NULL);
result[0] = '\0';
int maxL = 0;
// 枚举k,枚举值为回文字符串中心的位置, O(n^2)
for (int k = 0; k < length; k++)
{
char* center = str + k;
char* t = center;
char* s = center;
// center为中心,尽量向右扩展,单向扩展即可,并且如果发生扩展,那么可以优化k,k++直接向前一步,
while (t < str + length && *(t + 1) == *center)
{
k++;
t++;
}
// 同时向两边扩展,s向左,t向右,寻找回文
while (s > str&& t < str + length && *(s - 1) == *(t + 1))
{
s--;
t++;
}
// 结果处理
int sLen = t - s + 1; //回文子串的长度
if (sLen > maxL)
{
maxL = sLen;
strncpy(result, s, sLen);
result[sLen] = '\0';
}
}
return result;
}
测试用例:
输入
"babad" “bab”
"" ""
"a" "a"
"abadd" "aba"