LeetCode-5. Longest Palindromic Substring(最長迴文子串)
阿新 • • 發佈:2019-01-10
問題:給定一個字串 s
,找到 s
中最長的迴文子串。你可以假設 s
的最大長度為 1000。
Example 1:
Input: "babad"
Output: "bab"
Note: "aba" is also a valid answer.
Example 2:
Input: "cbbd"
Output: "bb"
方法一:暴力解法
容易想到的方法往往耗時。思路是醬紫噠:一段字串可能的最短迴文是單個字元,可能的最長迴文是它本身。那我們就設定一個視窗,長度從1到 len(s)。若有視窗長度w,依次以每個字元為起點,取長度為w的字串,注意最後一個起點不可能是最後一個字元,否則視窗就填不滿了。
#Python3 class Solution: def longestPalindrome(self, s): """ :type s: str :rtype: str """ l = 0;ans = "";a = b ="" for w in range(1,len(s)+1): #w為視窗長度 for i in range(0,len(s)-w+1): #每個視窗的起始位置,最後一個起點應是最後一個視窗的開頭 a = s[i:w+i];b = a[::-1] #取這段視窗的字串即其逆置字串 if a == b: #如果這個視窗內的字串和它的逆置字串相等,則它是迴文 if len(a) > l: #如果這段迴文比之前的迴文長,那把這段迴文作為最新答案 l = len(a) ans = a return ans
方法二:動態規劃
這個方法是對暴力解法的一個改進。暴力解法每次都要取字串並進行判斷,相當於把所有情況逐一列舉出來。但動態規劃對每次進行判斷時,只要知道上一次是什麼情況就可以了,也就是說只要我知道一個初始狀態,我就可以從這個初始狀態出發,根據一定的規則,依次推匯出後面各個狀態。首先定義 P(start,end),對於字串s[start,end],如果它是迴文,那麼P(start,end)為True,否則為False。那怎麼判斷s[start,end]是否是迴文?如果把該字串兩端去掉後,剩下的部分即s[start+1,end-1]是迴文,那麼只要s[start]==s[end],即新加上的兩端相同,那麼s[start,end]一定是迴文。但是長度為1和2時,不能用上面的方法,長度為2時,假設我們求P(1,2),那麼s[start+1,end-1]為s[2,1],實際情況不可能出現。
#Python
class Solution(object):
def longestPalindrome(self, s):
"""
:type s: str
:rtype: str
"""
maxL = 0;l = len(s);ans = "" #maxL記錄最大長度
p = [[False for _ in range(l)]for _ in range(l)] #生成二維陣列
for w in range(1,l+1): #從1開始取視窗大小
for start in range(0,l): #設定起點
end = start + w - 1
if end >= l: #如果終點超出所給字元總長,不合要求,結束本次迴圈
break
p[start][end] = (w == 1 or w == 2 or p[start+1][end-1]) and (s[start] == s[end]) #判斷條件
if p[start][end] and w > maxL: #如果是迴文且比之前的迴文都長
maxL = w;ans = s[start:end+1]
return ans
//C++
class Solution {
public:
string longestPalindrome(string s) {
int len = s.length();
if(len == 0) return "";
bool p[len][len];memset(p, false, sizeof(p)); //memset()對p進行初始化
int maxL = 0;
string ans = "";
for(int w = 1;w <= len;w++){
for(int start = 0;start < len;start++){
int end = start + w - 1;
if(end >= len)
break;
p[start][end] = (w == 1 || w == 2 || p[start+1][end-1]) && (s[start] == s[end]);
if(p[start][end] && w > maxL){
maxL = w;
ans = s.substr(start,w);
}
}
}
return ans;
}
};
其實官方總共給了5中解法,但是我覺得還是要根據自己的情況從自己能掌握的開始。後面孰能生巧了,再去掌握那些更高階的演算法。