[DP/BackTracking]115. Distinct Subsequences

  • 分類:DP/BackTracking
  • 時(shí)間復(fù)雜度: O(n^2)
  • 空間復(fù)雜度: O(n^2)-->O(n)因?yàn)橹缓蜕弦恍杏嘘P(guān)所以可以存上一行的數(shù)據(jù)

115. Distinct Subsequences

Given a string S and a string T, count the number of distinct subsequences of S which equals T.

A subsequence of a string is a new string which is formed from the original string by deleting some (can be none) of the characters without disturbing the relative positions of the remaining characters. (ie, "ACE" is a subsequence of "ABCDE" while "AEC" is not).

Example 1:

Input: S = "rabbbit", T = "rabbit"
Output: 3
Explanation:

As shown below, there are 3 ways you can generate "rabbit" from S.
(The caret symbol ^ means the chosen letters)

rabbbit
^^^^ ^^
rabbbit
^^ ^^^^
rabbbit
^^^ ^^^

Example 2:

Input: S = "babgbag", T = "bag"
Output: 5
Explanation:

As shown below, there are 5 ways you can generate "bag" from S.
(The caret symbol ^ means the chosen letters)

babgbag
^^ ^
babgbag
^^    ^
babgbag
^    ^^
babgbag
  ^  ^^
babgbag
    ^^^

代碼:

DP原始解法:

class Solution:
    def numDistinct(self, s: 'str', t: 'str') -> 'int':
        m=len(t)
        n=len(s)
        # init
        dp=[[0 for i in range(n+1)] for i in range(m+1)]
        dp[0]=[1 for i in range(n+1)]
        
        for i in range(1,m+1):
            for j in range(1,n+1):
                if t[i-1]==s[j-1]:
                    dp[i][j]=dp[i-1][j-1] #一種是match上了,一種是吧s[j]skip掉
                dp[i][j]+=dp[i][j-1]
                    
        return dp[-1][-1]

DPO(n)解法:

class Solution:
    def numDistinct(self, s: 'str', t: 'str') -> 'int':
        m=len(t)
        n=len(s)
        # init
        dp={0:[1 for i in range(n+1)],1:[0 for i in range(n+1)]}
        
        for i in range(1,m+1):
            for j in range(0,n+1):
                if j==0:
                    ans=0
                else:
                    if t[i-1]==s[j-1]:
                        ans+=dp[(i-1)%2][j-1]
                dp[(i)%2][j]=ans       
                    
        return dp[m%2][-1]

記憶化遞歸解法:

class Solution:
    def numDistinct(self, s: 'str', t: 'str') -> 'int':
        m=len(t)
        n=len(s)     
                    
        return self.helper(s,t,m,n,{})
    
    def helper(self,s,t,m,n,memo):
        
        if (m,n) in memo:
            return memo[(m,n)]
        
        #寫出口
        if m==0:
            return 1
        if n==0:
            return 0

        if s[n-1]==t[m-1]:
            res=self.helper(s,t,m-1,n-1,memo)+self.helper(s,t,m,n-1,memo)
        else:
            res=self.helper(s,t,m,n-1,memo)
            
        memo[(m,n)]=res
        return memo[(m,n)]

討論:

1.這道題是一道很難的DP(反正我覺得很難)
2.這道題的講解看的是公瑾講解
3.最主要的還是4個(gè)地方:

  • state: dp[i][j]代表num of subseq of s[1:j] equals t[1:i]
  • init:dp[0][*]=1 當(dāng)t為字符串的時(shí)候僅有1個(gè)解
  • function:如果兩個(gè)字符一樣,那么等于兩個(gè)字符之前的字符串的解加上skip掉s[j]的解,如果不一樣,那么直接是skip掉s[j]的解
  • ans
    4.這道題的O(n)方法也好難啊,主要還是要對著例子,逐一突破就做出來了
  1. 記憶化遞歸是個(gè)好方法簡單明了!
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • rljs by sennchi Timeline of History Part One The Cognitiv...
    sennchi閱讀 7,872評(píng)論 0 10
  • 入システムがこのほど
    828b2ef774a1閱讀 150評(píng)論 0 0
  • 編輯和作家分開,這事不好整,因?yàn)檎f實(shí)在的,不是我的興趣所在。我還是回歸本位,做一個(gè)作家,就得了。但是在看了那坦麗高...
    楊陽陽6閱讀 405評(píng)論 0 0
  • 文/沈煜倫 情書告訴我愛你 Day 2 就算是今天 ...
    星空下的向日葵閱讀 295評(píng)論 0 1
  • 注意: 1.打包方式不再是war2.基礎(chǔ)springboot父工工程 pom文件: 啟動(dòng)類:
    jiahzhon閱讀 289評(píng)論 0 0

友情鏈接更多精彩內(nèi)容