leetcode 115. Distinct Subsequences
一、问题描述
给定一个字符串S和一个字符串T,计算S的不同子序列的数目,它等于T.
字符串的子序列是由原始字符串形成的新字符串,通过删除字符中的一些(可以不是)而不干扰其余字符的相对位置。 (即“ACE”是“ABCDE”的子序列,而“AEC”不是)。
【举例】
<例1>
输入: S = "rabbbit", T = "rabbit"
输出: 3
解释:
如下所示,有三种方法可以从S生成“rabbit”。(脱字符号^表示选定的字母)
rabbbit
^^^^ ^^
rabbbit
^^ ^^^^
rabbbit
^^^ ^^^
<例2>输入: S = "babgbag", T = "bag"
输出: 5
解释:
如下所示,有5种方法可以从S生成“bag”。(脱字符号^表示选定的字母)
babgbag
^^ ^
babgbag
^^ ^
babgbag
^ ^^
babgbag
^ ^^
babgbag
^^^
二、问题分析
s = "babgbag" t="bag"
设f(i,j)为 t[0,,,j-1]在s[0,,,i-1]出现的次数,即长度为j的t串在长度为i的s串中出现的次数则状态转移方程为
f(i,j) = [
f(i-1,j) s[i-1] != s[j-1]
f(i-1,j)+f(i-1,j-1) s[i-1] == s[j-1]
]
边界条件划分:
- 当t为空串,s为非空串时,非空串包含空串。即f(i,0)=1
- 当t为非空串,s为空串时,空串不包含非空串。即f(0,j)=0
- 空串包含空串,即f(0,0)=1
三、解题算法
/************************************************************ Author:tmw date:2018-5-29 *************************************************************/ #include <stdio.h> #include <stdlib.h> #include <string.h> int numDistinct(char* s, char* t) { int s_len = strlen(s); int t_len = strlen(t); if(t_len>s_len) return 0; int i,j; int dp[s_len+2][t_len+2]; /** 非空串包含空串。即f(i,0)=1 空串不包含非空串。即f(0,j)=0 空串包含空串,即f(0,0)=1 **/ for(i=0;i<=s_len;i++) dp[i][0]=1; for(j=0;j<=t_len;j++) dp[0][j]=0; dp[0][0] = 1; for( i=1; i<=s_len; i++ ) { for( j=1; j<=t_len; j++ ) { if( s[i-1] != t[j-1] ) dp[i][j] = dp[i-1][j]; else dp[i][j] = dp[i-1][j] + dp[i-1][j-1]; } } return dp[s_len][t_len]; }
四、执行结果
accept
梦想还是要有的,万一实现了呢~~~ヾ(◍°∇°◍)ノ゙~~~~