代码随想录算法训练营第47天| 647. 回文子串、516.最长回文子序列

1. 647. 回文子串

题目链接:647. 回文子串
文档讲解: 代码随想录

(1)确定数组和下标
dp[i]包含元素 i 在内的回文子串数量(这样子写不出递推关系式)。dp[i][j]表示区间范围[i,j](左闭右闭)的子串是否是回文子串
(2)递推关系式
如果s[i]和s[j]相等,如果i=j,则dp[i][j]=True;如果j-i=1,dp[i][j]=True;如果j-i>1,当d[i+1][j-1]=True时,dp[i][j]=True。如果不相等,那么dp[i][j]=False
(3)初始化
都为False
(4)遍历顺序
dp[i + 1][j - 1] 在 dp[i][j]的左下角,遍历i从底向上,j从前往后
(5)打印数组

class Solution(object):
    def countSubstrings(self, s):
        """
        :type s: str
        :rtype: int
        """
        dp = [[False] * len(s) for _ in s]
        res = 0
        for i in range(len(s)-1,-1,-1):
            for j in range(i, len(s)): #要从i开始
                if s[i] == s[j]:
                    if j - i <= 1:
                        dp[i][j] = True
                        res += 1
                    elif dp[i+1][j-1]:
                        dp[i][j] = True
                        res += 1      
        return res

双指针:动态规划的空间复杂度偏高,为 O ( n 2 ) O(n^2) O(n2)。在遍历中心点的时候,要注意中心点有两种情况,一个元素可以作为中心点,两个元素也可以作为中心点。

class Solution(object):
    def countSubstrings(self, s):
        """
        :type s: str
        :rtype: int
        """
        res = 0
        for i in range(len(s)):
            res += self.ext(s, i, i, len(s))
            res += self.ext(s, i, i+1, len(s))
        return res
        
    def ext(self, s, i, j, n):
        res = 0
        while i >= 0 and j < n and s[i] == s[j]:
            i -= 1
            j += 1
            res += 1
        return res

2. 516.最长回文子序列

题目链接:516.最长回文子序列
文档讲解: 代码随想录

和上一题的区别在于不一定要连续。
(1)确定数组和下标
dp[i][j]表示区间范围[i,j]的最长回文子序列长度
(2)递推关系式
如果s[i]和s[j]相等,那么dp[i][j]=dp[i+1][j-1]+2;如果不等,dp[i][j]=max(dp[i+1][j],dp[i][j-1])
(3)初始化
dp[i][i]=1,其余为0
(4)遍历顺序
i 从后往前,j 从前往后
(5)打印数组

class Solution(object):
    def longestPalindromeSubseq(self, s):
        """
        :type s: str
        :rtype: int
        """
        dp = [[0] * len(s) for _ in s]
        for i in range(len(s)):
            dp[i][i] = 1
        for i in range(len(s)-2,-1,-1):
            for j in range(i+1,len(s)):
                if s[i] == s[j]:
                    dp[i][j] = dp[i+1][j-1] + 2
                else:
                    dp[i][j] = max(dp[i+1][j],dp[i][j-1])
        return dp[0][-1]
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值