[LeetCode] Distinct Subsequences 不同的子序列

简介:

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

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).

Here is an example:
S = "rabbbit", T = "rabbit"

Return 3.

看到有关字符串的子序列或者配准类的问题,首先应该考虑的就是用动态规划Dynamic Programming来求解,这个应成为条件反射。而所有DP问题的核心就是找出递推公式,想这道题就是递推一个二维的dp数组,下面我们从题目中给的例子来分析,这个二维dp数组应为:

  Ø r a b b b i t
Ø 1 1 1 1 1 1 1 1
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,因为非空字符串不能当空字符串的子序列。理清这些,二维数组dp的边缘便可以初始化了,下面只要找出递推式,就可以更新整个dp数组了。我们通过观察上面的二维数组可以发现,当更新到dp[i][j]时,dp[i][j] >= dp[i][j - 1] 总是成立,再进一步观察发现,当 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) {
        int dp[T.size() + 1][S.size() + 1];
        for (int i = 0; i <= S.size(); ++i) dp[0][i] = 1;    
        for (int i = 1; i <= T.size(); ++i) dp[i][0] = 0;    
        for (int i = 1; i <= T.size(); ++i) {
            for (int j = 1; j <= S.size(); ++j) {
                dp[i][j] = dp[i][j - 1] + (T[i - 1] == S[j - 1] ? dp[i - 1][j - 1] : 0);
            }
        }
        return dp[T.size()][S.size()];
    }
};

本文转自博客园Grandyang的博客,原文链接:不同的子序列[LeetCode] Distinct Subsequences ,如需转载请自行联系原博主。

相关文章
|
3月前
代码随想录 Day46 动态规划14 LeetCode T392 判断子序列 T115 不同的子序列
代码随想录 Day46 动态规划14 LeetCode T392 判断子序列 T115 不同的子序列
37 0
|
1月前
|
算法 Java
[Java·算法·简单] LeetCode 392. 判断子序列 详细解读
[Java·算法·简单] LeetCode 392. 判断子序列 详细解读
22 0
|
6月前
【Leetcode -575.分糖果 -594.最长和谐子序列】
【Leetcode -575.分糖果 -594.最长和谐子序列】
35 0
|
6月前
【Leetcode -389.找不同 -392.判断子序列】
【Leetcode -389.找不同 -392.判断子序列】
32 0
|
3月前
|
Java
leetcode 516. 最长回文子序列(JAVA)题解
leetcode 516. 最长回文子序列(JAVA)题解
22 0
|
3月前
|
算法 测试技术 C#
【单调队列】LeetCode1425:带限制的子序列和
【单调队列】LeetCode1425:带限制的子序列和
【单调队列】LeetCode1425:带限制的子序列和
|
3月前
|
算法 测试技术 C#
【二分查找】【双指针】LeetCode:2565最少得分子序列
【二分查找】【双指针】LeetCode:2565最少得分子序列
|
3月前
|
存储
leetcode-940:不同的子序列 II
leetcode-940:不同的子序列 II
22 0
|
3月前
|
Go
golang力扣leetcode 1332. 删除回文子序列
golang力扣leetcode 1332. 删除回文子序列
10 0
|
3月前
leetcode-115:不同的子序列
leetcode-115:不同的子序列
15 0