代码随想录算法训练营第49天 | 动态规划总结

代码随想录算法训练营第天 |

647.回文子串
https://leetcode.cn/problems/palindromic-substrings/description/
代码随想录
https://programmercarl.com/0647.回文子串.html#思路
516.最长回文子序列
https://leetcode.cn/problems/longest-palindromic-subsequence/
代码随想录
https://programmercarl.com/0516.最长回文子序列.html#思路

647. 回文子串

  • dp[i][j]的定义
    • 布尔类型的dp[i][j]:表示区间范围[i,j] (注意是左闭右闭)的子串是否是回文子串,如果是dp[i][j]为true,否则为false。
  • 递推公式
    • s[i]!=s[j] 说明两端不同 一定不是 dp[i][j]= Flase
    • s[i]==s[j]:分类讨论情况
      1. i和j相同 同一个字符串一定是
      2. i-j==1 差一个也是回文字符串
      3. i-1>1 如果dp[i+1][j-1]是回文字符串 这个也一定是
  • 初始化:全部为false
  • 遍历顺序
    • 遍历顺序由上面的依赖条件决定;这里dp[i+1][j-1]得到dp[i][j]。所以从左下向右上遍历
点击查看代码
class Solution:
    def countSubstrings(self, s: str) -> int:
        dp = [[False]*len(s) for _ in range(len(s))]
        res = 0
        for i in range(len(s)-1,-1,-1):
            for j in range(i,len(s)):
                if s[i]==s[j]:
                    if abs(i-j)<2:
                        dp[i][j] = True
                        res = res+1
                    else:
                        if dp[i+1][j-1]:
                            dp[i][j] = True
                            res = res+1
        return res

516. 最长回文子序列

  • 回文子序列和回文序列的区别:如果两个序列不一样的话,选取左右两侧的最大值;
  • 即使内部的子序列不是回文序列也可以;只需要在相同时增加长度即可;
点击查看代码
class Solution:
    def longestPalindromeSubseq(self, s: str) -> int:
        dp = [[0]*len(s) for _ in range(len(s))]
        max_length = 0
        for i in range(len(s)-1,-1,-1):
            for j in range(i,len(s)):
                if s[i]==s[j]:
                    if i==j:
                        dp[i][j] = 1
                    else:
                        dp[i][j] = dp[i+1][j-1]+2
                else:
                    dp[i][j] = max(dp[i+1][j],dp[i][j-1])
                if dp[i][j]>max_length:
                    max_length = dp[i][j]
        # print(np.array(dp))
        return max_length
posted @   哆啦**  阅读(4)  评论(0编辑  收藏  举报
努力加载评论中...
点击右上角即可分享
微信分享提示