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
.
Code:
思路:
类似于数字分解的题目。dp[i][j]表示:b的前j个字符在a的前i个字符中出现的次数。
似乎这种表示方法司空见惯,但是一开始我还真没能搞懂如何去递推。事情的真相是:
如果a[i] == b[j]则 dp[i][j] = dp[i-1][j] + dp[i-1][j-1]
如果a[i] != b[j]则 dp[i][j] = dp[i-1][j]
如果S[i]==T[j],那么dp[i][j] = dp[i-1][j-1] + dp[i-1][j]。意思是:如果当前S[i]==T[j],那么当前这个字母即可以保留也可以抛弃,所以变换方法等于保留这个字母的变换方法加上不用这个字母的变换方法。如果S[i]!=T[i],那么dp[i][j] = dp[i-1][j],意思是如果当前字符不等,那么就只能抛弃当前这个字符。
/**
* @author 作者 E-mail:
* @version 创建时间:2015年7月8日 下午4:11:33
* 类说明
*/
public class LeetCode115 {
public static int numDistinct(String s, String t) {
int temp[] = new int[t.length()];
for(int i = 0;i<s.length();i++){
for(int j = 0;j<t.length();j++){
if(s.charAt(i) == t.charAt(j)){
if(j==0){
temp[j]++;
break;
}else{
temp[j]+=temp[j-1];
}
}
}
}
return temp[t.length()-1];
}
public static int numDistinct1(String S, String T) {
if(S==null||T==null) {
return 0;
}
if(S.length()<T.length()) {
return 0;
}
//递推公式用的
int [][] dp = new int[S.length()+1][T.length()+1];
dp[0][0] = 1;
//任意一个字符串变换成一个空串都只有一种变换方法
for(int i=0;i<S.length();i++) {
dp[i][0] = 1;
}
//递推公式
for(int i=1;i<=S.length();i++) {
for(int j=1;j<=T.length();j++) {
//如果S和T的当前字符相等,那么有两种选法;否则S的当前字符不能要
dp[i][j] = dp[i-1][j];
if(S.charAt(i-1)==T.charAt(j-1)) {
dp[i][j] += dp[i-1][j-1];
}
}
}
return dp[S.length()][T.length()];
}
//308msAC
public static int numDistinct2(String S, String T) {
if(S==null||T==null) {
return 0;
}
if(S.length()<T.length()) {
return 0;
}
int [][] dp = new int[S.length()][T.length()];
int temp = 0;
for(int i=0;i<S.length();i++) { //col
if(T.charAt(0)==S.charAt(i)){
dp[i][0]=++temp;
}else{
dp[i][0]=temp;
}
}
for(int i=1;i<S.length();i++) {
for(int j=1;j<T.length()&&j<=i;j++) {
System.out.println("i: " + i+"j: " + j);
dp[i][j] = dp[i-1][j];
if(S.charAt(i)==T.charAt(j)) {
dp[i][j] += dp[i-1][j-1];
}
}
}
return dp[S.length()-1][T.length()-1];
}
public static void main(String[] args) {
String s = "aabb";
String t = "ab";
System.out.println("numDistinct: " + numDistinct(s, t));
System.out.println("numDistinct1: " + numDistinct1(s, t));
System.out.println("numDistinct2: " + numDistinct2(s, t));
}
}