最長回文子串

2021-06-21 20:15:40 字數 2409 閱讀 6838

給定乙個字串,找出該字串的最長回文子串。回文字串指的就是從左右兩邊看都一樣的字串,如aba,cddc都是回文字串。字串abbacdc存在的回文子串有abba和cdc,因此它的最長回文子串為abba。

初看這個問題可能想到這樣的方法:對字串s逆序得到新的字串s',再求s和s'的最長公共子串,這樣求出的就是最長回文子串。

如s="caba", s'="abac",則s和s'的最長公共子串為aba,這個是正確的。

但是如果s = 「abacdfgdcaba」, s』 = 「abacdgfdcaba」,則s和s'的最長公共子串為abacd,顯然這不是回文字串。因此這種方法是錯誤的。

要找出最長回文子串,首先要解決判斷乙個字串是否是回文字串的問題。最顯而易見的方法是設定兩個變數i和j,分別指向字串首部和尾部,比較是否相等,然後i++,j--,直到i >= j為止。下面的**是判斷字串str[i, j]是不是回文字串,即字串str從i到j的這一段子串是否是回文字串,在後面會用到這個方法。

[cpp]view plain

copy

bool

ispalindrome(string str, 

intstart, 

intend)   

return

true

;  }  

蠻力法通過對字串所有子串進行判斷,如果是回文字串,則更新最長回文的長度。因為長度為n的字串的子串一共可能有(1+n)*n/2個,每次判斷子串需要o(n)的時間,所以一共需要o(n^3)時間來求取最長回文子串。

[cpp]view plain

copy

string longestpalindrome(string str)   

}  }  }  

return

str.substr(start, max);   

}  

因為蠻力法判定回文的時候需要很多重複的計算,所以可以通過動態規劃法來改進該演算法。假定我們知道「bab」是回文,則「ababa」也一定是回文。

[cpp]view plain

copy

定義p[i, j] = 

true

如果子串s[i, j]是回文字串。  

則 p[i, j] <- (p[i+1, j-1] && s[i]==s[j])。  

base case如下:

[cpp]view plain

copy

p[ i, i ] ← 

true

p[ i, i+1 ] ← ( si = si+1 )  

據此動態規劃方法的**如下,

該方法的時間複雜度為o(n^2),空間複雜度為o(n^2)。

[cpp]view plain

copy

string longestpalindromedp(string s)  

;  for

(int

i=0; i

table[i][i] = true

;  for

(int

i=0; i

if(s[i] == s[i+1])   

}  /*依次求table[i][i+2]...table[i][i+n-1]等*/

for(

intlen=3; len<=n; ++len)   

}  }  

return

s.substr(longestbegin, maxlen);  

}  

還有乙個更簡單的方法可以使用o(n^2)時間、不需要額外的空間求最長回文子串。我們知道回文字串是以字串中心對稱的,如abba以及aba等。乙個更好的辦法是從中間開始判斷,因為回文字串以字串中心對稱。乙個長度為n的字串可能的對稱中心有2n-1個,至於這裡為什麼是2n-1而不是n個,是因為可能對稱的點可能是兩個字元之間,比如abba的對稱點就是第乙個字母b和第二個字母b的中間。因此可以依次對2n-1個中心點進行判斷,求出最長的回文字串即可。根據該思路可以寫出下面的**。

[cpp]view plain

copy

string expandaroundcenter(string s, 

intl, 

intr)  

return

s.substr(l+1, r-l-1);  

}  string longestpalindrome3(string s)  

return

longest;  

}  

最長回文子串 最長回文子串行

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,且佔據單獨一行,輸出最長的回文子串 如有多個,輸出,起始位置最...