给定一个字符串s,s中只包含数字,请返回s中最长的特殊的回文子串的长度
特殊的回文子串t满足
t进行任何次交换后可以变成一个回文字符申
输入格式:
输入第一行包含一个字符串s
输出格式:
特殊的回文子串的最长长度
有无给个正确算法
算法思路:
C语言实现:
#include <stdio.h>
#include <string.h>
int is_palindrome(char *s, int start, int end) {
while (start < end) {
if (s[start] != s[end]) {
return 0;
}
start++;
end--;
}
return 1;
}
int longest_special_palindrome(char *s) {
int n = strlen(s);
int max_len = 0;
/* 判断s本身是否为回文串 */
if (is_palindrome(s, 0, n - 1)) {
return n;
}
/* 以每个字符为中心向两侧扩展 */
for (int i = 0; i < n; i++) {
int len = 1;
while (i - len >= 0 && i + len < n && s[i - len] == s[i + len]) {
len++;
}
if (len > 1) {
/* 对于每个回文子串,交换其中的字符判断是否为特殊回文子串 */
for (int j = i - len + 1; j <= i + len - 1; j++) {
for (int k = j + 1; k <= i + len - 1; k++) {
char tmp = s[j];
s[j] = s[k];
s[k] = tmp;
if (is_palindrome(s, i - len + 1, i + len - 1)) {
max_len = len;
}
/* 恢复原来的字符串 */
tmp = s[j];
s[j] = s[k];
s[k] = tmp;
}
}
}
}
return max_len;
}
int main() {
char s[100];
scanf("%s", s);
int len = longest_special_palindrome(s);
printf("%d\n", len);
return 0;
}
时间复杂度:$O(n^3)$,其中$n$为字符串s的长度。
参考GPT和自己的思路:对于这个问题,可以使用Manacher算法来解决。Manacher算法是用来求解一个字符串中最长回文子串的算法,它的时间复杂度为O(N)。
具体实现方式可以参考一下代码:
#include <iostream>
#include <cstring>
using namespace std;
const int N = 2e5 + 10;
char s[N], ns[N * 2];
int p[N * 2];
int Init()
{
int n = strlen(s);
ns[0] = '#';
for (int i = 0; i < n; i ++)
{
ns[i * 2 + 1] = s[i];
ns[i * 2 + 2] = '#';
}
return n * 2 + 1;
}
int Manacher(int len)
{
int maxn = 0, id = 0;
for (int i = 0; i < len; i ++)
{
p[i] = maxn > i ? min(p[2 * id - i], maxn - i) : 1;
while (i >= p[i] && ns[i - p[i]] == ns[i + p[i]]) p[i] ++;
if (i + p[i] > maxn)
{
maxn = i + p[i];
id = i;
}
}
int res = 1;
for (int i = 0; i < len; i ++)
res = max(res, p[i] - 1);
return res;
}
int main()
{
cin >> s;
int len = Init();
int ans = Manacher(len);
cout << ans << endl;
return 0;
}
具体思路可以参考以下链接:[Manacher算法详解](https://www.cnblogs.com/kuaileyonghe