647. 回文子串
516.最长回文子序列
动态规划总结篇
647. 回文子串
dp[i][j]为[i,j]是否为回文串
这里要注意的是我们的遍历顺序,不能是i一遍,j一遍这样,因为会包含后面的信息
所以我们这里选择的是先遍历长度,然后再遍历首字符
class Solution: def countSubstrings(self, s: str) -> int: n = len(s) dp = [[False for _ in range(n+1)] for _ in range(n+1)] ans = n for i in range(n+1): dp[i][i] = True for l in range(2, n+1): for i in range(n-l+1): if s[i] == s[i+l-1]: if i+1 <= i+l-2: if dp[i+1][i+l-2]: dp[i][i+l-1] = True ans += 1 else: dp[i][i+l-1] = True ans += 1 return ans
参考答案非常机智!!!
首先看这幅图,在我们需要知道dp[i][j]是否为回文子串的前提是知道dp[i+1][j-1]
所以!!!
i是从大到小进行遍历, j是从小到大进行遍历。所以!!非常有意思。
并且在进行判断的时候,使用i-j<=1 然后进行dp[i][i+l-1] = True,这样的话可读性更强
class Solution: def countSubstrings(self, s: str) -> int: dp = [[False] * 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] and (j - i <= 1 or dp[i+1][j-1]): result += 1 dp[i][j] = True return result
双指针法
动态规划的空间复杂度是偏高的,我们再看一下双指针法。
首先确定回文串,就是找中心然后向两边扩散看是不是对称的就可以了。
在遍历中心点的时候,要注意中心点有两种情况。
一个元素可以作为中心点,两个元素也可以作为中心点。
那么有人同学问了,三个元素还可以做中心点呢。其实三个元素就可以由一个元素左右添加元素得到,四个元素则可以由两个元素左右添加元素得到。
所以我们在计算的时候,要注意一个元素为中心点和两个元素为中心点的情况。
class Solution: def countSubstrings(self, s: str) -> int: result = 0 for i in range(len(s)): result += self.extend(s, i, i, len(s)) #以i为中心 result += self.extend(s, i, i+1, len(s)) #以i和i+1为中心 return result def extend(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
516.最长回文子序列
dp[i][j]的定义是[i,j]最长的回文序列
if s[i] == s[j] : dp[i][j] = dp[i+1][j-1]+2
if s[i] != s[j]: dp[i][j] = max(dp[i+1][j], dp[i][j-1])
一个从正面,一个反面
j > i
class Solution: def longestPalindromeSubseq(self, s: str) -> int: dp = [[0] * len(s) for _ in range(len(s))] for i in range(len(s)): dp[i][i] = 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]
动态规划最强总结篇!
动规五部曲分别为:
- 确定dp数组(dp table)以及下标的含义
- 确定递推公式
- dp数组如何初始化
- 确定遍历顺序
- 举例推导dp数组
动规专题刚开始的时候,讲的题目比较简单,不少录友和我反应:这么简单的题目 讲的复杂了,不用那么多步骤分析,想出递推公式直接就AC这道题目了。