給定乙個字串,找出該字串的最長回文子串。回文字串指的就是從左右兩邊看都一樣的字串,如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,且佔據單獨一行,輸出最長的回文子串 如有多個,輸出,起始位置最...