5. 最长回文子串 (从今天开始刷动态规划50题)

 

 

 

 

给定一个字符串 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]



posted @ 2020-02-01 15:53  ChevisZhang  阅读(172)  评论(0编辑  收藏  举报