打卡Day47
1. 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]
882

被折叠的 条评论
为什么被折叠?



