Given a string s, find the longest palindromic substring in s. You may assume that the maximum length of s is 1000.
Example 1:
Input: “babad”
Output: “bab”
Note: “aba” is also a valid answer.
Example 2:
Input: “cbbd”
Output: “bb”
1.暴力遍历
遍历算法是我们最直观的解法,事实上也能通过OJ。我们使用的方法是两重循环确定子串的起始和结束位置,这样只要判断该子串是个回文,我们保留最长的回文即可。
class Solution {
public:
string longestPalindrome(string s) {
int len = s.size();
string res;
for(int i=0;i<len;i++){
for(int j=i;j<len;j++){
if(j-i+1>=res.size() && isPalindrome(s,i,j)){
res = s.substr(i,j-i+1);
}
}
}
return res;
}
bool isPalindrome(string &s,int start,int end){
int len = s.size();
int l =start,r=end;
while(l<=r){
if(s[l++]!=s[r--]){
return false;
}
}
return true;
}
};
2.动态规划
我们维护一个二维数组dp,其中dp[i][j]表示字符串区间[i, j]是否为回文串,当i = j时,只有一个字符,肯定是回文串,如果i = j + 1,说明是相邻字符,此时需要判断s[i]是否等于s[j],如果i和j不相邻,即i - j >= 2时,除了判断s[i]和s[j]相等之外,dp[j + 1][i - 1]若为真,就是回文串,通过以上分析,可以写出递推式如下:
dp[i, j] = 1 if i == j
= s[i] == s[j] if j = i + 1
= s[i] == s[j] && dp[i + 1][j - 1] if j > i + 1
class Solution(object):
def longestPalindrome(self, s):
"""
:type s: str
:rtype: str
"""
if len(set(s)) == 1:
return s
n = len(s)
start,end,maxL=0,0,0
dp = [[0]*n for _ in range(n)]
for i in range(n):
for j in range(i):
dp[j][i]=(s[j]==s[i])&((i-j<2)|dp[j+1][i-1])
if dp[j][i] and maxL<i-j+1:
maxL=i-j+1
start=j
end=i
dp[i][i]=1
return s[start:end+1]
3.中心扩展法:
'''
中心扩展法
step 1:遍历每个字符,把每个字符当做中心逐步向两边扩展,每扩展一步就得到一个新的子串。
这里针对输入字符串的长度,扩展方式需要根据长度奇偶性质做判断。
Step 2:判断子串是否为回文串,更新当前最长回文串
Step 3:返回最长回文串
'''
class Solution(object):
def longestPalindrome(self, s):
res = ""
for i in xrange(len(s)):
# odd case, like "aba"
tmp = self.helper(s, i, i)
if len(tmp) > len(res):
res = tmp
# even case, like "abba"
tmp = self.helper(s, i, i+1)
if len(tmp) > len(res):
res = tmp
return res
# get the longest palindrome, l, r are the middle indexes
# from inner to outer
def helper(self, s, l, r):
while l >= 0 and r < len(s) and s[l] == s[r]:
l -= 1; r += 1
return s[l+1:r]