给定一个字符串 s
,找到 s
中最长的回文子串。你可以假设 s
的最大长度为 1000。
法1:暴力法,三层遍历,两层头节点尾节点,再用一层判断是否是回文
法2:动态规划,两层遍历,两层头节点尾节点,判断是否为回文可以直接访问 dp[i][j] , 这样就用 n^2的空间 换了 n的时间
本题我用的动态回归, 动态回归的本质就是空间换时间(本题的最佳评论是这么说的)
特殊之处:
本题的状态转移方程是:
dp[i][j] = s[i] == s[j] and dp[i+1][j-1]
根据状态转移方程,可知,
i层,j列的dp要用到 i+1层的 j-1列的数据,所以遍历的顺序要 从三角形的 角开始遍历,不能从三角形的头开始遍历!!!
固定了上界,倒叙遍历下届,用状态转移方程更新DP。
for j in range(1,len(s)):
for i in range(j-1,-1,-1):
收获:
1.熟悉了动态规划流程
2.知道了 动态规划的 遍历顺序取决于状态方程
class Solution:
def longestPalindrome(self, s: str) -> str:
#初始化 dp
if len(s)<2:
return s
dp = [[False for _ in range(len(s))] for _ in range(len(s))]
for i in range(len(s)):dp[i][i] = True
for j in range(1,len(s)):
for i in range(j-1,-1,-1):
if s[i] == s[j]:
if j-i<3: dp[i][j] = True
if dp[i+1][j-1]: dp[i][j] = True
res = [-1,'']
for j in range(1,len(s)):
for i in range(j,-1,-1):
if j-i+1 > res[0] and dp[i][j]: res = [j-i+1,s[i:j+1]]
return res[1]