# Question

Formatted question description: https://leetcode.ca/all/115.html

Given two strings s and t, return the number of distinct subsequences of s which equals t.

The test cases are generated so that the answer fits on a 32-bit signed integer.

Example 1:

Input: s = "rabbbit", t = "rabbit"
Output: 3
Explanation:
As shown below, there are 3 ways you can generate "rabbit" from s.
rabbbit
rabbbit
rabbbit


Example 2:

Input: s = "babgbag", t = "bag"
Output: 5
Explanation:
As shown below, there are 5 ways you can generate "bag" from s.
babgbag
babgbag
babgbag
babgbag
babgbag

Constraints:

• 1 <= s.length, t.length <= 1000
• s and t consist of English letters.

# Algorithm

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

dp[0][0] = 1; // T and S are both empty strings.
dp[0][1 ... S.length()-1] = 1; // T is an empty string, S has only one subsequence match.
dp[1 ... T.length()-1][0] = 0; // S is an empty string, T is not an empty string, and S has no subsequence matching.
dp[i][j] = dp[i][j-1] + (T[i-1] == S[j-1]? dp[i-1][j-1]: 0)


# Code

• 
public class Distinct_Subsequences {

public class Solution_iteration {
public int numDistinct(String s, String t) {

if (s == null || t == null)     return 0;
if (s.length() < t.length())    return 0;

int TLength = t.length();
int SLength = s.length();

int[][] dp = new int[TLength + 1][SLength + 1];
dp[0][0] = 1;

for (int i = 1; i <= SLength; i++) {
dp[0][i] = 1;
}
for (int i = 1; i <= TLength; i++) {
dp[i][0] = 0;
}

for (int i = 1; i <= TLength; i++) {
for (int j = 1; j <= SLength; j++) {
if (t.charAt(i - 1) == s.charAt(j - 1)) {
dp[i][j] = dp[i][j - 1] + dp[i - 1][j - 1];
} else {
dp[i][j] = dp[i][j - 1];
}
}
}

return dp[TLength][SLength];
}
}

/*
Last executed input:
"aabdbaabeeadcbbdedacbbeecbabebaeeecaeabaedadcbdbcdaabebdadbbaeabdadeaabbabbecebbebcaddaacccebeaeedababedeacdeaaaeeaecbe"
"bddabdcae"
*/
public class Solution_recursion {
public int numDistinct(String s, String t) {

if (s.length() == 0) {
return t.length() == 0 ? 1 : 0;
}

if (t.length() == 0) {
return s.length() >= 0 ? 1 : 0; // @note: t is empty, so delete all in s is one solution
}

if (s.length() < t.length()) {
return 0;
}

int sum = 0;

if (s.charAt(0) == t.charAt(0)) {
sum += numDistinct(s.substring(1), t.substring(1));
}

sum += numDistinct(s.substring(1), t); // @note: anyway, have to try this one: eg, s='aa' and t='a', result=2

return sum;

}
}

}

############

class Solution {
public int numDistinct(String s, String t) {
int m = s.length(), n = t.length();
int[][] dp = new int[m + 1][n + 1];
for (int i = 0; i <= m; ++i) {
dp[i][0] = 1;
}
for (int i = 1; i <= m; ++i) {
for (int j = 1; j <= n; ++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[m][n];
}
}

• // OJ: https://leetcode.com/problems/distinct-subsequences
// Time: O(MN)
// Space: O(N)
class Solution {
public:
int numDistinct(string s, string t) {
int M = s.size(), N = t.size();
vector<long> dp(N + 1);
dp[0] = 1;
for (int i = 0; i < M; ++i) {
for (int j = N - 1; j >= 0; --j) {
if (s[i] == t[j]) dp[j + 1] += dp[j];
if (dp[j + 1] > INT_MAX) dp[j + 1] = 0;
}
}
return dp[N];
}
};

• class Solution:
def numDistinct(self, s: str, t: str) -> int:
m, n = len(s), len(t)
dp = [[0] * (n + 1) for _ in range(m + 1)]
for i in range(m + 1):
dp[i][0] = 1
for i in range(1, m + 1):
for j in range(1, n + 1):
dp[i][j] = dp[i - 1][j]
if s[i - 1] == t[j - 1]:
dp[i][j] += dp[i - 1][j - 1]
return dp[m][n]

############

class Solution(object):
# space O(n^2)
def _numDistinct(self, s, t):
"""
:type s: str
:type t: str
:rtype: int
"""
dp = [[0] * (len(t) + 1) for _ in range(0, len(s) + 1)]

for i in range(0, len(s) + 1):
dp[i][0] = 1

for i in range(1, len(s) + 1):
for j in range(1, len(t) + 1):
dp[i][j] += dp[i - 1][j]
if t[j - 1] == s[i - 1]:
dp[i][j] += dp[i - 1][j - 1]

return dp[-1][-1]

def numDistinct(self, s, t):
"""
:type s: str
:type t: str
:rtype: int
"""
dp = [0] * (len(t) + 1)
for i in range(1, len(s) + 1):
pre = 1
for j in range(1, len(t) + 1):
tmp = dp[j]
if t[j - 1] == s[i - 1]:
dp[j] += pre
pre = tmp
return dp[-1]


• func numDistinct(s string, t string) int {
m, n := len(s), len(t)
dp := make([][]int, m+1)
for i := 0; i <= m; i++ {
dp[i] = make([]int, n+1)
dp[i][0] = 1
}
for i := 1; i <= m; i++ {
for j := 1; j <= n; j++ {
dp[i][j] = dp[i-1][j]
if s[i-1] == t[j-1] {
dp[i][j] += dp[i-1][j-1]
}
}
}
return dp[m][n]
}


• function numDistinct(s: string, t: string): number {
const m = s.length;
const n = t.length;
const dp: number[][] = new Array(m + 1)
.fill(0)
.map(() => new Array(n + 1).fill(0));
for (let i = 0; i <= m; ++i) {
dp[i][0] = 1;
}
for (let i = 1; i <= m; ++i) {
for (let j = 1; j <= n; ++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[m][n];
}