115. Distinct Subsequences 不同的子序列

題目鏈接
tag:

  • Hard;

question:
??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
^^^

思路:
??看到有關字符串的子序列或者配準類的問題,首先應該考慮的就是用動態(tài)規(guī)劃Dynamic Programming來求解,這個應成為條件反射。而所有DP問題的核心就是找出遞推公式,想這道題就是遞推一個二維的dp數(shù)組,下面我們從題目中給的例子來分析,這個二維dp數(shù)組應為:

? r a b b b i t
? 1 1 1 1 1 1 11
r 0 1 1 1 1 1 1 1
a 0 0 1 1 1 1 1 1
b 0 0 0 1 2 3 3 3
b 0 0 0 0 1 3 3 3
i 0 0 0 0 0 0 3 3
t 0 0 0 0 0 0 0 3

?? 首先,若原字符串和子序列都為空時,返回1,因為空串也是空串的一個子序列。若原字符串不為空,而子序列為空,也返回1,因為空串也是任意字符串的一個子序列。而當原字符串為空,子序列不為空時,返回0,因為非空字符串不能當空字符串的子序列。理清這些,二維數(shù)組dp的邊緣便可以初始化了,下面只要找出遞推式,就可以更新整個dp數(shù)組了。我們通過觀察上面的二維數(shù)組可以發(fā)現(xiàn),當更新到dp[i][j]時,dp[i][j] >= dp[i][j - 1] 總是成立,再進一步觀察發(fā)現(xiàn),當 T[i - 1] == S[j - 1] 時,dp[i][j] = dp[i][j - 1] + dp[i - 1][j - 1],若不等, dp[i][j] = dp[i][j - 1],所以,綜合以上,遞推式為:

??dp[i][j] = dp[i][j - 1] + (T[i - 1] == S[j - 1] ? dp[i - 1][j - 1] : 0)

代碼如下:

class Solution {
public:
    int numDistinct(string s, string t) {
        if (s.size() < t.size())
            return 0;
        int n1=t.size(), n2=s.size();
        long dp[n1+1][n2+1];
        
        for (int i=0; i<=n1; ++i)
            dp[i][0] = 0;
        for (int i=0; i<=n2; ++i)
            dp[0][i] = 1;
        
        for (int i=1; i<=n1; ++i) {
            for (int j=1; j<=n2; ++j) {
                if (t[i-1] == s[j-1])
                    dp[i][j] = dp[i][j-1] + dp[i-1][j-1];
                else
                    dp[i][j] = dp[i][j-1];
            }
        }
        return dp[n1][n2];
    }
};
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

  • 在C語言中,五種基本數(shù)據(jù)類型存儲空間長度的排列順序是: A)char B)char=int<=float C)ch...
    夏天再來閱讀 4,031評論 0 2
  • "use strict";function _classCallCheck(e,t){if(!(e instanc...
    久些閱讀 2,142評論 0 2
  • 基礎概念 字符串:S[0..n],S是一個字符串,長度為n。S本質上是一個字符數(shù)組,數(shù)組的每個元素都是一個字符; ...
    RobotBerry閱讀 1,230評論 0 3
  • Lua 5.1 參考手冊 by Roberto Ierusalimschy, Luiz Henrique de F...
    蘇黎九歌閱讀 14,246評論 0 38
  • 很長時間沒安心的看書,朋友的電話一掛,白駒般出門練攤,一杯一杯的扎啤,腦袋里蓄滿水??粗笥讶锎号ㄩ_,宅在家里...
    尚無三言閱讀 504評論 0 0

友情鏈接更多精彩內容