原題
給出字符串S和字符串T,計算S的不同的子序列中T出現的個數。
子序列字符串是原始字符串通過刪除一些(或零個)產生的一個新的字符串,并且對剩下的字符的相對位置沒有影響。(比如,“ACE”是“ABCDE”的子序列字符串,而“AEC”不是)。
樣例
給出S = "rabbbit", T =** "rabbit"**
返回 3
解題思路
典型動態規劃 - Two Sequence DP
狀態cache[i][j]表示 S前i位的不同子序列中有幾個和T的前j位相同
初始化
cache[0][0] = 1 T和S都是空串,空串在空串中出現1次
cache[0][j] = 1 T是空串,S只有一種子序列(空串)可以匹配
cache[i][0] = 0 S是空串,T不是空串,S沒有子序列可以匹配
狀態轉移方程
當S[j] != T[i]的時候, cache[i][j] = cache[i][j - 1] //"ABCD"匹配"AC"的方式至少有"ABC"匹配"AC"那么多種
當S[j] == T[i]的時候,還要加上cache[i - 1][j - 1]那么多種匹配方式
如果狀態轉移方程比較難想,可以先畫圖找規律
Screenshot at Jun 05 00-07-26.png
完整代碼
class Solution(object):
def numDistinct(self, s, t):
"""
:type s: str
:type t: str
:rtype: int
"""
if not s:
return 0
if not t:
return 1
cache = [[0 for j in range(len(s) + 1)] for i in range(len(t) + 1)]
for j in range(len(s) + 1):
cache[0][j] = 1
for i in range(1, len(t) + 1):
for j in range(1, len(s) + 1):
if s[j - 1] == t[i - 1]:
cache[i][j] = cache[i][j - 1] + cache[i - 1][j - 1]
else:
cache[i][j] = cache[i][j - 1]
return cache[len(t)][len(s)]