这道题可以用双指针解决。下面是我的解题思考:
1.首先最长重复某字符的子串肯定是对称的,例如...ssssffssBou...,毫无疑问ssss是对称的,所以第一步可以考虑寻找最长重复字符的子串。可以这么操作,我们将left指示ssss的起始位置,假设是i,则初始时left=i,right=i,然后right向右移动,判断right+1,right+2,right+3......是否和i位置的s相等
2.经过第一步后,此时right+1的字符和前面的最长重复字符不一样,按照上面的例子,ssss的下一个f不是s,此时我们right恰好指向ssss的最右端的s.
3.接着判断最长重复字符字符串左右两端的字符是否对称。即判断left-1和right+1,left-2和right+2,left-j和right+j是否对称
4.每轮获取到的最长长度即right-left+1,同时更新最终的最长长度即可。
C代码如下:
#include<stdio.h>
int main()
{
char str[10001];
char ch = '\0';
int length = 0;
//读取字符串
while((ch = getchar()) != '\n')
{
str[length++] = ch;
}
str[length] = '\0';
int i = 0;
//start记录最长字符串的起始位置,end记录最长字符串的结束位置,本题不用输出,可以不用它们
//但是如果需要指明最长对称字符串在哪里,它们是谁时,就会派上用场
//int start = 0,end = 0;
int res = 0; //最长对称字符串的长度
while(i < length)
{
int left = i,right = i;
//寻找最长重复的字符的字符串,例如aaaaaabaaa,最长的就是aaaaa,到b停止
//为什么这么操作?因为最长重复的字符的字符串它本身就是对称字符串
//所以先找到左右不等的位置
while(right + 1 < length && str[left] == str[right + 1])
{
++right;
}
//找到以后呢?
//此时的right是最长重复字符字符串的最右端,按上面的例子aaaaaabaaa
//right是b,下面判断right右边的字符和left左边的字符是否也对称,即相等
while(left > 0 && right + 1 < length && str[left - 1] == str[right + 1])
{
--left;
++right;
}
//此时left~right之间的字符串就是本次循环截取到的最长对称字符串
//需要和上一次获得的结果进行比较,判断哪次是最长的
int newMaxLength = right - left + 1;
if(newMaxLength > res)
{
res = newMaxLength;
//start = left;
//end = right;
}
++i;
}
printf("%d\n",res);
return 0;
}
下面是java代码实现:
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
String str = scanner.nextLine();
int res = 0;
int start = 0, end = 0;
for (int i = 0; i < str.length(); i++) {
int l = i, r = i;
while (r + 1 < str.length() && str.charAt(r + 1) == str.charAt(i)) r++;
while (l > 0 && r + 1 < str.length() && str.charAt(l - 1) == str.charAt(r + 1)) {
l--;
r++;
}
int newMaxLength = r - l + 1;
if (newMaxLength > res) {
res = newMaxLength;
start = l;
end = r;
}
}
//最长对称子串的长度
System.out.println(res);
//输出这个最长对称子串
System.out.println(str.substring(start, end + 1));
}