[LeetCode] Distinct Subsequences

[Problem]

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.


[Analysis]

方法一:递归
    每次递归调用f(S, T)使用如下方法处理(假设S长度为n,T长度为m):
    找出T[0]在S中的第一个位置i,则f(S, T) = f(S[i+1:n], T[1:m])
    则复杂度为f(n) = n*f(n-1) = n*(n-1)*f(n-2) = ... = n!
    Large Judge时容易TLE。

方法二:动态规划
    假设S长度为n,T长度为m,使用m×n的数组array,用array[i][j]记录T[i]与S[j]进行匹配时,可以使用的方法数。从i=m-1,j=n-1开始,按照i--,j--进行二重循环的扫描:
    当i == m-1时,if(T[i] == S[j])array[i][j] = array[i][j+1]+1,否则array[i][j] = array[i][j+1];
    当i < m-1时,if(T[i] == S[j])array[i][j] = array[i][j+1] + array[i+1][j+1],否则array[i][j] = array[i][j+1];
    返回array[0][0].复杂度为O(n^)

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

[Solution]

方法一:递归(过Large Judge会TLE)

int numDistinct(string S, string T) {
// Start typing your C/C++ solution below
// DO NOT write int main() function
int len1 = S.length();
int len2 = T.length();

if(len1 == 0 && len2 == 0){
return 1;
}
else if(len1 == 0){
return 0;
}
else if(len2 == 0){
return 1;
}
else{
int res = 0;
for(int i = 0; i < len1; ++i){
if(S[i] == T[0]){
res += numDistinct(S.substr(i+1, len1-i-1), T.substr(1, len2-1));
}
}
return res;
}
}


方法二:动态规划

class Solution {
public:
int numDistinct(string S, string T) {
// Start typing your C/C++ solution below
// DO NOT write int main() function
int len1 = S.length();
int len2 = T.length();

// both of them are empty strings
if(len1 == 0 && len2 == 0){
return 1;
}
// S is an empty string
else if(len1 == 0){
return 0;
}
// T is an empty string
else if(len2 == 0){
return 1;
}

// neither of them is empty
int array[len2+1][len1+1];
memset(array, 0, sizeof(array));
for(int i = len2-1; i >= 0; --i){
for(int j = len1-1; j >= 0; --j){
// the two characters are the same
if(T[i] == S[j]){
if(i == len2-1){
array[i][j] = array[i][j+1] + 1;
}
else{
array[i][j] = array[i][j+1] + array[i+1][j+1];
}
}
else{
array[i][j] = array[i][j+1];
}
}
}
return array[0][0];
}
};


说明:版权所有,转载请注明出处。 Coder007的博客
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值