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
.
通过删除字符,有多少种办法将S变成T?
直接做:
public int numDistinct(String s, String t) { int M = s.length(), N = t.length(); if (M < N) return 0; if (N == 0) return 1;//如果t是空字符串,那么s删除所有字符,即1种方式 if (s.charAt(0) == t.charAt(0)) return numDistinct(s.substring(1), t) + numDistinct(s.substring(1), t.substring(1)); else return numDistinct(s.substring(1), t);//不等于的话,去掉s的当前字符,继续和t比较 }肯定超时了,所以这种情况下,就改成dp了。
方法一:好理解
public int numDistinct(String S, String T) {
int lenS = S.length(), lenT = T.length();
if (lenS < lenT) return 0;
int[][] dp = new int[lenS + 1][lenT + 1];
for (int i = 0; i <= lenS; ++i)
dp[i][0] = 1;
for (int i = 1; i <= lenS; ++i)
for (int j = 1; j <= lenT && j <= i; ++j) {
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[lenS][lenT];
}
方法二 使用一维数组,
Runtime:
3 ms beats 99.40% of java submissions.
public int numDistinct(String s, String t) {
int M = s.length(), N = t.length();
int[] dp = new int[N + 1];//dp[x]=numDistinct(s,t.substring(0,x))
char[] ss = s.toCharArray(), tt = t.toCharArray();
dp[0] = 1;
for (int i = 1; i <= M; i++) {
for (int j = N; j > 0; j--) {
if (ss[i - 1] == tt[j - 1]) {
dp[j] += dp[j - 1];
}
}
}
return dp[N];
}