代码随想录第57天|647. 回文子串、516. 最长回文子序列

38 阅读1分钟

647. 回文子串

1. doc reading

class Solution:
    def countSubstrings(self, s: str) -> int:
        s = list(s)
        dp = [[False] * len(s) for _ in range(len(s))]
        count = 0
        for i in range(len(s) - 1, -1, -1):
            for j in range(i, len(s)):
                if s[i] == s[j]:
                    if j == i:
                        dp[i][j] = True
                    elif j == i + 1:
                        dp[i][j] = True
                    else:
                        dp[i][j] = dp[i + 1][j - 1]
                    if dp[i][j]:
                        count += 1
        return count
  1. 注意递推顺序
  2. 另外,一般dp都是求什么是什么,但是回文串这个不行,因为求什么是什么难以继续递推。

516. 最长回文子序列

1. doc reading

如果s[i]与s[j]不相同,说明s[i]和s[j]的同时加入 并不能增加[i,j]区间回文子序列的长度,那么分别加入s[i]、s[j]看看哪一个可以组成最长的回文子序列。

加入s[j]的回文子序列长度为dp[i + 1][j]。

加入s[i]的回文子序列长度为dp[i][j - 1]。

那么dp[i][j]一定是取最大的,即:dp[i][j] = max(dp[i + 1][j], dp[i][j - 1]);

如果s[i]与s[j]相同,那么dp[i][j] = dp[i + 1][j - 1] + 2;

class Solution:
    def longestPalindromeSubseq(self, s: str) -> int:
        dp = [[0] * len(s) for _ in range(len(s))]
        max_len = 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
                    elif (i + 1 == j):
                        dp[i][j] = 2
                    else:
                        dp[i][j] = dp[i + 1][j - 1] + 2
                else:
                    dp[i][j] = max(dp[i + 1][j], dp[i][j - 1])
                max_len = max(max_len, dp[i][j])
        # print(dp)
        return max_len