解决两个字符串的动态规划问题,一般都是用两个指针 i,j 分别指向两个字符串的最后,然后一步步往前走,缩小问题的规模。
class Solution:
def numDistinct(self, s: str, t: str) -> int:
'''
state: dp[i][j]表示t[j:]在s[i:]中出现的次数
basecase: j=n时t为'',空字符串在任意字符串中出现次数均为1,
所以有dp[:][-1]=1
transfer: 当s[i]==t[j]时,若s[i]选择不与t[j]匹配,此时出现次数为dp[i+1][j],
若s[i]选择与t[j]匹配,则出现次数为dp[i+1][j+1],
所以有dp[i][j]=dp[i+1][j+1]+dp[i+1][j];
当s[i]!=t[j]时,s[i]无法与t[j]匹配,出现次数只能继承dp[i+1][j],
所以此时dp[i][j]=dp[i+1][j]。
result: dp[0][0]
'''
m, n = len(s), len(t)
dp = [[0]* (n+1) for _ in range(m+1)]
for i in range(m+1):
dp[i][-1] = 1
for j in range(n-1, -1, -1):
for i in range(m-1, -1, -1):
if s[i] == t[j]:
dp[i][j] = dp[i+1][j] + dp[i+1][j+1]
else:
dp[i][j] = dp[i+1][j]