来源 https://blog.csdn.net/bailang_zhizun/article/details/80538774
1、题目
给定一个字符串 s,找到 s 中最长的回文子串。你可以假设 s 的最大长度为1000。
示例 1:
输入: "babad"
输出: "bab"
注意: "aba"也是一个有效答案。
示例 2:
输入: "cbbd"
输出: "bb"
2、求解
2.1 暴力解法
首先暴力解法,对于j in range(0, len), i in range(0, j+1),提取出所有s的子串,然后判断该子串是否是回文子串
时间复杂度O(n^3)
2.2 动态规划(普通版本)
用f(i,j)表示s[i:j+1]是否是回文串,则状态转移公式可以写成:
用一个矩阵存储f(i, j)的值,再计算所有可能子串的f(i, j)值
class Solution(object):
def longestPalindrome(self, s):
"""
:type s: str
:rtype: str
"""
LEN = len(s)
f = [[0 for i in range(LEN)] for i in range(LEN)]
longest_str = ""
for j in range(0, LEN):
for i in range(0, j+1):
if j-i<=1 and s[i]==s[j]:
f[i][j]=1
if len(longest_str)<j-i+1:
longest_str = s[i:j+1]
elif j-i>1 and s[i]==s[j] and f[i+1][j-1]:
f[i][j]=1
if len(longest_str)<j-i+1:
longest_str = s[i:j+1]
return longest_str
动态规划的时间、空间复杂度均为O(n2)
2.3 动态规划升级版
改进上一个方法,空间复杂度为O(n2)需要保存所有f(i, j),但是真实情况下,f(i, j)只和j-1相关, 所以每次只保存j-1所有子串是否是回文串就可以了,这样空间复杂度就降到了O(2n),即O(n)
class Solution(object):
def longestPalindrome(self, s):
"""
:type s: str
:rtype: str
"""
LEN = len(s)
f1 = [0 for i in range(LEN)]
f2 = [0 for i in range(LEN)]
longest_str = ""
for j in range(0, LEN):
for i in range(0, j+1):
if j-i<=1 and s[i]==s[j]:
f2[i]=1
if len(longest_str)<j-i+1:
longest_str = s[i:j+1]
elif j-i>1 and s[i]==s[j] and f1[i+1]:
f2[i]=1
if len(longest_str)<j-i+1:
longest_str = s[i:j+1]
f1 = f2
f2 = [0 for i in range(LEN)]
return longest_str