主要内容
动态规划问题完结
动态规划题目
647. 回文子串
思路分析
动态规划解法:
1.含义:dp[i][j]表示字符s[i,j]区间的回文子串的数量
2.递推公式:
if s[i]==s[j]:
if j - i <= 1:d[i][j]=True 二者是同一个或挨着
else:dp[i][j]=dp[i+1][j-1]
3.初始化均为False
4.遍历顺序从下到上 从左到右
双指针解法:
以 i 为中心扩展,以 i, i + 1 为中心扩展
代码
# 动态规划
class Solution:
# 1.含义:dp[i][j]表示字符s[i,j]区间的回文子串的数量
# 2.递推公式:
# if s[i]==s[j]:
# if j - i <= 1:d[i][j]=True 二者是同一个或挨着
# else:dp[i][j]=dp[i+1][j-1]
# 3.初始化均为False
# 4.遍历顺序从下到上 从左到右
def countSubstrings(self, s: str) -> int:
n = len(s)
res = 0
dp = [[False] * n for _ in range(n)]
for i in range(n-1, -1, -1):
for j in range(i, n):
if s[i] == s[j]:
if j - i <= 1:
res += 1
dp[i][j] = True
elif dp[i + 1][j - 1]:
res += 1
dp[i][j] = True
return res
# 双指针
class Solution:
def countSubstrings(self, s: str) -> int:
ans=0
for i in range(len(s)):
for j in range(2):
ans+=self.expand(s,i,i+j)
return ans
def expand(self,s,begin,end):
cnt=0
while(begin>=0 and end<len(s) and s[begin]==s[end]):
cnt+=1
begin-=1
end+=1
return cnt
516.最长回文子序列
思路分析
代码
class Solution:
# 1. 含义:dp[i][j]表示s的[i,j]区间内回文子序列的长度
# 2. 递推:if s[i] == [j]:dp[i][j] = dp[i+1][j-1]+2
# else: dp[i][j] = max(dp[i][j - 1], dp[i + 1][j])
# 3. 初始化:dp[i][i] = 1
# 4. 遍历顺序:从下到上,从左到右 j从i+1开始
def longestPalindromeSubseq(self, s: str) -> int:
n = len(s)
dp = [[0] * n for _ in range(n)]
for i in range(n):
dp[i][i] = 1
for i in range(n, -1, -1):
for j in range(i + 1, n):
if s[i] == s[j]:
dp[i][j] = dp[i+1][j-1]+2
else:
dp[i][j] = max(dp[i][j - 1], dp[i + 1][j])
return dp[0][n-1]