* DP - Top Down
* Matrix - Memoization
* Time O(N * M) | Space (N * M)
* https://leetcode.com/problems/distinct-subsequences/
* @param {string} s
* @param {string} t
* @return {number}
*/
var numDistinct = (s, t, i = 0, j = 0, memo = initMemo(s, t)) => {
const isBaseCase1 = s.length < t.length;
if (isBaseCase1) return 0;
const isBaseCase2 = j === t.length;
if (isBaseCase2) return 1;
const isBaseCase3 = i === s.length;
if (isBaseCase3) return 0;
const hasSeen = memo[i][j] !== null;
if (hasSeen) return memo[i][j];
return dfs(
s,
t,
i,
j,
memo,
);
};
var initMemo = (s, t) =>
new Array(s.length).fill().map(() => new Array(t.length).fill(null));
var dfs = (s, t, i, j, memo) => {
const left = numDistinct(
s,
t,
i + 1,
j,
memo,
);
const isEqual = s[i] === t[j];
const right = isEqual
? numDistinct(
s,
t,
i + 1,
j + 1,
memo,
)
: 0;
memo[i][j] = left + right;
return memo[i][j];
};
* DP - Bottom Up
* Matrix - Tabulation
* Time O(N * M) | Space (N * M)
* https://leetcode.com/problems/distinct-subsequences/
* @param {string} s
* @param {string} t
* @return {number}
*/
var numDistinct = (s, t) => {
const tabu = initTabu(s, t);
search(s, t, tabu);
return tabu[0][0];
};
var initTabu = (s, t) => {
const tabu = new Array(s.length + 1)
.fill()
.map(() => new Array(t.length + 1));
tabu[s.length].fill(0);
for (let r = 0; r <= s.length; ++r) {
tabu[r][t.length] = 1;
}
return tabu;
};
var search = (s, t, tabu) => {
for (let r = s.length - 1; 0 <= r; r--) {
for (let c = t.length - 1; 0 <= c; c--) {
const left = tabu[r + 1][c];
const isEqual = s[r] === t[c];
const right = isEqual ? tabu[r + 1][c + 1] : 0;
tabu[r][c] = left + right;
}
}
};
* DP - Bottom Up
* Matrix - Tabulation
* Time O(N * M) | Space O(M)
* https://leetcode.com/problems/distinct-subsequences/
* @param {string} s
* @param {string} t
* @return {number}
*/
var numDistinct = (s, t) => {
const tabu = initTabu(t);
search(s, t, tabu);
return tabu[0];
};
var initTabu = (t) => new Array(t.length).fill(0);
var search = (s, t, tabu) => {
for (let row = s.length - 1; 0 <= row; row--) {
let prev = 1;
for (let col = t.length - 1; 0 <= col; col--) {
const curr = tabu[col];
const isEqual = s[row] === t[col];
if (isEqual) tabu[col] += prev;
prev = curr;
}
}
};