Problem Description給出一個只由小寫英文字元a,b,c...y,z組成的字串S,求S中最長迴文串的長度.
迴文就是正反讀都是一樣的字串,如aba, abba等
Input輸入有多組case,不超過120組,每組輸入為一行小寫英文字元a,b,c...y,z組成的字串S
兩組case之間由空行隔開(該空行不用處理)
字串長度len <= 110000
Output每一行一個整數x,對應一組case,表示該組case的字串中所包含的最長迴文長度.
Sample Input
aaaaabab
Sample Output
43
一 對於str,比較好點的演算法可能是把迴文串分奇數長度和偶數長度,然後遍曆i (0,1,……len),遍曆j
(1)奇數長度迴文串:每次比較str【i - j】跟str【i+j】,只要不一樣就進入下一個i;
(2)偶數長度迴文串:每次比較str【】跟str【i+j】,只要不一樣就進入下一個i;
雖然這樣算不會有str【i】跟str【j】之間的重複比較,但是如果是一個全部字元都一樣的str,例如“aaaaaaaaaaaa”,那麼演算法效率還是0(n*n);
二
我們可以這樣做:
(1)求出包以連續相同子串在中間的最長迴文,因為上面的演算法中i的位置就在迴文串中間,只需要0(n)就可以算出來;
(2)對於一中所描述的演算法,奇數迴文串a,只要a的長度大於或者等於3,那麼相應i的偶數長度的迴文串就可以不用計算了,因為該偶數長度的迴文串要麼小於2,要麼就是該迴文所有字元都一樣,而所有的字元一樣迴文串在(1)中已經計算了;
給出證明:如果該偶數迴文串長度大於或者等於2
對於奇數長度大於3迴文串有str【i + 1】= str【i - 1】,那麼對應的偶數迴文串一定有str[i] == str[i + 1];由這兩個式子得到str【i - 1】 = str【i】= str【i + 1】即證明了(2)結論;
(3)相應的如果偶數迴文串長度大於2,那麼下一個奇數迴文串跟偶數迴文串都不用算;同樣的證明方法;
那麼我們的演算法就出來了;
給出我上面的題目的代碼,進一步進行分析
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
#define MAX 220001
char str[MAX];
int Max(int a, int b)
{
return a > b ? a : b;
}
int getSame()//求以連續相同字元為中間地方的最長迴文串
{
int i;
int start, end;
int max = 1;
for(i = 0; str[i]; i ++)
{
if(i == 0)
{
start = 0;
}
if(str[i + 1] != str[start])
{
end = i;
if(start != end)
{
for(; start >= 0 && str[end]; start --,end ++)
{
if(str[start] != str[end])
break;
}
max = Max(max, end - start - 1);
}
start = i + 1;
}
}
return max;
}
int get()
{
int i, j = 0; //開始初始化上次所求的迴文串長度的一半,因為j就是記錄的一半
int a;
int max = 1;
for(i = 0; str[i + 1]; i ++)
{
if(str[i] == str[i + 1])
continue;
if(j > 1) //只要上次偶數迴文串所求的長度大於2就可以不用計算這一次的奇數迴文了
{
j = 0;
continue;
}
for(j = 1;str[i + j] && i - j >= 0 && str[i + j] == str[i - j]; j ++)
a = 1;
max = Max(max, j * 2 - 1);
if(j > 1) //只要這次的奇數迴文串長度大於等於3就不用計算這一次的偶數迴文串了
{
j = 0;
continue;
}
for(j = 1; str[i + j] && i - j + 1 >= 0 && str[i + j] == str[i - j + 1]; j ++)
a = 1;
max = Max(max, j * 2 - 2);
}
return max;
}
int main()
{
int max = 1;
while(scanf("%s", str) != EOF)
{
max = getSame();
max = Max(max, get());
printf("%d\n", max);
}
return 0;
}
還是那句話,如果不是很理解可以追問,我再解釋了…………………………看了一下在hdoj上面的排名,自己的250ms排在50名,真不知道哪些nb們怎麼能100ms過的,坑啊