写代码的第四十天!!!!
动态规划最后一天!!!!
647. 回文子串
思路
完全是卡哥的思路,完完全全!
解决问题1:dp[i][j]的含义是什么?在数组中i到j是否是回文串。
解决问题2:递推公式是什么?就是s[i]与s[j]相等,s[i]与s[j]不也就是就一个字符,所以是回文子串;情况二:下标i 与 j相差为1,例如aa,也是回文子串;情况三:下标:i 与 j相差大于1的时候,例如cabac,此时s[i]与s[j]已经相同了,我们看i到j区间是不是回文子串就看aba是不是回文就可以了,那么aba的区间就是 i+1 与 j-1区间,这个区间是不是回文就看dp[i + 1][j - 1]是否为true。不相等的情况就是直接False即可。
解决问题3:初始化?不涉及具体数字,直接初始化为false即可。
解决问题4:遍历顺序?按照上面的递推公式情况,可以看出ij和i+1以及j-1有关所以是从下往上,从左往右遍历。
正确代码:
class Solution:
def countSubstrings(self, s: str) -> int:
dp = [[False for _ in range(len(s))] for _ in range(len(s))]
result = 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 <= 1:
result += 1
dp[i][j] = True
elif dp[i+1][j-1]:
result += 1
dp[i][j] = True
return result
516.最长回文子序列
思路
本题不要求是连续的情况。
要求的就是最大长度。
解决问题1:dp[i][j]的含义是什么?代表i到j的最大回文串的长度。
解决问题2:递推公式是什么?如果s[i]==s[j]那么就证明回文串长度可以dp[i+1][j-1]加2了,如果不等于那么不变,那么要么是dp[i+1][j],要么是dp[i][j-1],要求的是最大长度,所以应该是max(dp[i+1][j],dp[i][j-1])
解决问题3:dp数组的初始化?这个初始化是我想不到的,根本想不到,初始化的是i= =j的情况dp[i][j]=1,其他位置随意。
解决问题4:遍历顺序?按照递推公式,从下到上,从左到右。
正确代码:
class Solution:
def longestPalindromeSubseq(self, s: str) -> int:
dp = [[0 for _ in range(len(s))] for _ in range(len(s))]
for i in range(len(s)):
for j in range(len(s)):
if i == j:
dp[i][j] = 1
for i in range(len(s)-1,-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]