最長回文子串一般有以下兩種情況:
問題描述1:給定乙個字串,求它的最長回文子串的長度,並且回文子串的字元在原字串中必須連續。
分析:很明顯可以使用暴力法求解,列舉出所有的子串,分別判斷其是否為回文。但是這種方法效率比較低,而且時間複雜度太高,並且如果乙個長的子串包含另乙個短一些的子串,那麼對子串的回文判斷其實是不需要的,等等。
我們可以對其進行優化,因為回文串是以中間的字元為中心左右對稱的,例如回文串「aba」,以b為中心,它的左端和右端對稱,都是a。
所以我們可以列舉中心位置,從中心位置向兩邊擴充套件,記錄並更新得到的最長的回文長度。這裡要注意回文串的長度是計數還是偶數,因此需要分別進行討論。
具體的j**a**如下,語句都很通用,讀者可以很容易的轉換為其他語言:
1view codeimport j**a.util.*;
2class
test
18return max; //
返回回文串長度
19} 20}
2122
public
class
main
2728 }
問題描述2:給定乙個字串,求它的最長回文子串的長度,並且回文子串的字元在原字串中可以不連續。也就是說可以刪除原字串中的乙個或多個字元。
分析:該問題與問題1相比,有了一定的難度,難度在於可以刪除原字串中的字元,但是基本思想還是和問題1一樣,需要在問題1上做一些改進。
同樣需要分別考慮回文串是奇數還是偶數,無論哪種情況,都遵循這個過程。
當掃瞄到兩端字元相等時,兩端都要擴充套件,如果不相等,則要分兩步進行:
第一步,固定右端,向左掃瞄一遍,如果發現相等,則兩端同時擴充套件,長度加2.否則左指標-1
第二步,固定左端,向右掃瞄一遍,如果發現相等,則兩端同時擴充套件,長度加2.否則右指標+1
具體的j**a**如下,**寫法比較通用,讀者可以很容易轉換為其他語言。
1view codeimport j**a.util.*;
2class
test
20else
28 low=t;
29while(low>=0 && ++high//
左端固定不變,向右掃瞄一遍
30if(str.charat(low)==str.charat(high)) //
掃瞄到相等時,兩邊同時擴充套件,長度加2
3135}36
}37if(p>max)max=p; //
更新最長長度
3839 p=0; //
尋找以i-1,i為中心的偶數長度的回文
40 low=i-1;high=i;
41while(low>=0 && high
4249
else
57 low=t;
58while(low>=0 && ++high//
左端固定不變,向右掃瞄一遍
59if(str.charat(low)==str.charat(high)) //
掃瞄到相等時,兩邊同時擴充套件,長度加2
6064}65
}66if(p>max)max=p; //
更新最長長度
67}
68if(max==0)max=1; //
因為只要字串不為空,回文串最少也為1
69return max; //
返回回文串長度
70} 71}
7273
public
class
main
7879 }
最長回文子串 最長回文子串行
1.最長回文子串行 可以不連續 include include include include using namespace std 遞迴方法,求解最長回文子串行 intlps char str,int i,int j intmain include include include using n...
最長回文子串
描述 輸入乙個字串,求出其中最長的回文子串。子串的含義是 在原串連續出現的字串片段。回文的含義是 正著看和倒著看是相同的,如abba和abbebba。在判斷是要求忽略所有的標點和空格,且忽略大小寫,但輸出時按原樣輸出 首尾不要輸出多餘的字串 輸入字串長度大於等於1小於等於5000,且單獨佔一行 如果...
最長回文子串
輸入乙個字元,求出其中最長的回文子串。子串的含義是 在元串中連續出現的字串片段。回文的含義是 正看和倒看相同,如abba和yyxyy,在判斷時候應該忽略所有的空格和標點符號,且忽略大小寫,但輸出應該保持原樣,輸入的字元長度不超過5000,且佔據單獨一行,輸出最長的回文子串 如有多個,輸出,起始位置最...