原题目
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"
思路
第一遍解法
网上好的解法
# DP 解法
# O(n)=n^2 S(n)=n^2
class Solution:
def longestPalindrome(self, s):
l = len(s)
# 初始化二维数组
isPalindrome = [[False for i in range(l)] for i in range(l)]
max = 0
ans = ""
for j in range(l):
for i in range(j+1):
isPalindrome[i][j] = s[i] == s[j] and (j-i<=2 or isPalindrome[i+1][j-1] == True)
if isPalindrome[i][j] and j-i+1 > max:
max = j-i+1
ans = s[i:j+1]
return ans
# 中心扩散法
# O(n)=n^2 S(n)=0
class Solution:
def longestPalindrome(self, s):
ans = ""
for i in range(len(s)):
tmp = self.helper(s, i, i)
if len(tmp) > len(ans):
ans = tmp
tmp = self.helper(s, i, i+1)
if len(tmp) > len(ans):
ans = tmp
return ans
def helper(self, s, left, right):
while left>=0 and right<len(s) and s[left] == s[right]:
left += 1
right -= 1
return s[left+1:right]
获得的思考
- DP 解法
求字符串中的最长回文串,可以计算每个字符的最长回文串,所有字符里面最长的回文串就是整个字符串的最长回文串。用一个二维数组记录从前面的字符到后面字符是否是回文串,是回文串且长度比当前最长的回文串长,那么这个回文串就成为新的最长回文串。
- 初始化二维数组:用列表生成式方便快捷
[[False for i in range(l)] for i in range(l)]
- 字符串是否是回文串的判断条件
isPalindrome[i][j] = s[i]==s[j] and (j-i<=2 or isPalindrome[i+1][j-1]==True)
-
字符串开头和末尾字符相同
-
中间的字符(串)也是回文串(末尾 - 开头 >= 2)
- 两次遍历的位置
for j in range(l): # 字符串序号 0~len(s)-1
for i in range(j+1): # 确保能遍历到jj,bool[j][j]为True
- 中心扩散法
回文串从中心向两侧是对称相同的。而回文串有两种形式:
一种是形如a b a
这种对称中心是一个字符的字符串
一种是形如a b b a
这种对称中心是两个字符的字符串
同样的,遍历字符串,找到最长的回文串就是所求的答案。因为有两种形式的回文串,需要分别判断是哪一种形式的回文串。这里用一个helper()
函数接收字符串并返回接收的字符串的最长回文串,后面的两个参数实现了判断回文串两种形式的功能。
- 对每个字符分别查找形式一和形式二的最长回文串
tmp = self.helper(s, i, i)
tmp = self.helper(s, i, i+1)
helper()
函数中跳出 while 循环的时候 left 和 right 都超过最长回文串的边界,所以返回的是 left+1 到 right-1
return s[left+1:right]