详细见:leetcode.com/problems/distinct-subsequences
Java Solution: github
package leetcode;
/*
* 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.
*/
public class P115_DistinctSubsequences {
public static void main(String[] args) {
Solution2 solution = new Solution2();
String s = null, t = null;
s = ""; t = "";
System.out.println(solution.numDistinct(s, t));
s = "abbc"; t = "ab";
System.out.println(solution.numDistinct(s, t));
s = "rabbbit"; t = "rabbit";
System.out.println(solution.numDistinct(s, t));
s = "aaaaaaa"; t = "aaa";
System.out.println(solution.numDistinct(s, t));
s = "aaaaaaaq"; t = "aaaq";
System.out.println(solution.numDistinct(s, t));
s = "aaq"; t = "aaaaaaaaq";
System.out.println(solution.numDistinct(s, t));
}
/*
* 递归是为DP做准备
*/
static class Solution1 {
char[] sc = null, tc = null;
public int numDistinct(String s, String t) {
if (s == null || t == null) {
return t == null ? 1 : 0;
}
sc = s.toCharArray();
tc = t.toCharArray();
return numDistinct(0, sc.length - 1, 0, tc.length - 1);
}
private int numDistinct(int i, int j, int k, int l) {
if (j - i < l - k) {
return 0;
}
if (k > l) {
return 1;
}
if (sc[i] != tc[k]) {
return numDistinct(i + 1, j, k, l);
} else {
return numDistinct(i + 1, j, k, l) + numDistinct(i + 1, j, k + 1, l);
}
}
}
/*
* 这种问题毫无疑问第一方法DP
* AC
* 15 ms
* 对于这种问题,最好先写出递归版本,对应递归版本,写出dp版本
*/
static class Solution2 {
int[][] dp = null;
int len1, len2;
public int numDistinct(String s, String t) {
if (s == null || t == null) {
return t == null ? 1 : 0;
}
len1 = s.length();
len2 = t.length();
if (len1 < len2) {
return 0;
}
if (len2 == 0) {
return 1;
}
dp = new int[len1 + 1][len2 + 1];
for (int i = 0; i <= len1; i ++) {
dp[i][len2] = 1;
}
for (int i = len1 - 1; i > -1; i --) {
for (int j = len2 - 1; j > -1; j --) {
dp[i][j] = dp[i + 1][j] +(s.charAt(i) == t.charAt(j) ? dp[i + 1][j + 1] : 0);
}
}
return dp[0][0];
}
}
}
C Solution: github
/*
url: leetcode.com/problems/distinct-subsequences
unrecur: AC 6ms 33.33%
unrecur2: AC 3ms 58.33%
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
//TLE
int recur(char* s, char* t) {
if (*t == '\0') return 1;
if (*s == '\0') return 0;
if (*s == *t) return recur(s+1, t) + recur(s+1, t+1);
else return recur(s+1, t);
}
int unrecur(char* s, char* t) {
int sn = s == NULL ? 0 : strlen(s);
int tn = t == NULL ? 0 : strlen(t);
int i = 0, j = 0, ans = 0;
int** m = (int**) malloc(sizeof(int*) * (sn+1));
for (i = 0; i <= sn; i ++) {
m[i] = (int*) malloc(sizeof(int) * (tn+1));
for (j = 0; j <= tn; j ++) m[i][j] = 0;
}
for (i = 0, j = tn; i <= sn; i ++) m[i][j] = 1;
for (i = sn-1; i > -1; i --) {
for (j = tn-1; j > -1; j --) {
if (s[i] == t[j]) {
m[i][j] = m[i+1][j] + m[i+1][j+1];
} else {
m[i][j] = m[i+1][j];
}
}
}
ans = m[0][0];
for (i = 0; i <= sn; i ++) free(m[i]);
free(m);
return ans;
}
int unrecur2(char* s, char* t) {
int sn = s == NULL ? 0 : strlen(s);
int tn = t == NULL ? 0 : strlen(t);
int i = 0, j = 0, ans = 0, pre = 0, tmp;
int* m = (int*) malloc(sizeof(int) * (tn));
for (j = 0; j < tn; j ++) m[j] = 0;
for (i = sn-1; i > -1; i --) {
pre = 1;
for (j = tn-1; j > -1; j --) {
tmp = m[j];
if (s[i] == t[j]) {
m[j] += pre;
}
pre = tmp;
}
}
ans = m[0];
free(m);
return ans;
}
int numDistinct(char* s, char* t) {
return unrecur2(s, t);
}
int main() {
char* s = "rraaat";
char* t = "rat";
printf("%d\r\n", unrecur2(s, t));
printf("%d\r\n", unrecur(s, t));
}
Python Solution: github
#coding=utf-8
'''
url: leetcode.com/problems/distinct-subsequences
@author: zxwtry
@email: zxwtry@qq.com
@date: 2017年5月1日
@details: Solution: 129ms 87.80%
'''
class Solution(object):
def numDistinct(self, s, t):
"""
:type s: str
:type t: str
:rtype: int
"""
sn = 0 if s == None else len(s)
tn = 0 if t == None else len(t)
if (tn == 0): return sn
if (sn < tn): return 0
m = [0] * tn
for i in range(sn-1, -1, -1):
p = 1
for j in range(tn-1, -1, -1):
g = m[j]
if (s[i] == t[j]):
m[j] += p
p = g
return m[0]
if __name__ == "__main__":
s = "aaa"
t = "a"
print(Solution().numDistinct(s, t))