最長迴文高效演算法 HDOJ3068

來源:互聯網
上載者:User

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過的,坑啊

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.