π One-stop destination for all your technical interview Preparation π
Given two strings s and t, return the number of distinct subsequences of s which equals t.
A stringβs subsequence is a new string formed from the original string by deleting some (can be none) of the characters without disturbing the remaining charactersβ relative positions. (i.e., βACEβ is a subsequence of βABCDEβ while βAECβ is not).
The test cases are generated so that the answer fits on a 32-bit signed integer.
f(i,j)
represents the number of subsequences of t[0..j]
present in s[0..i]
.s
and t
and move forward in both strings.s
and move forward in s
only.s
. So we move forward in s
only.class Solution {
int f(int i, int j, string& s, string& t)
{
if (j < 0) return 1;
if (i < 0) return 0;
if (s[i] == t[j]) {
int take = f(i - 1, j - 1, s, t);
int notTake = f(i - 1, j, s, t);
return take + notTake;
}
int reduce = f(i - 1, j, s, t);
return reduce;
}
public:
int numDistinct(string s, string t)
{
int n = s.size(), m = t.size();
return f(n - 1, m - 1, s, t);
}
};
class Solution {
int f(int i, int j, string& s, string& t, vector<vector<double>>& dp)
{
if (j < 0) return 1;
if (i < 0) return 0;
if (dp[i][j] != -1) return dp[i][j];
if (s[i] == t[j]) {
int take = f(i - 1, j - 1, s, t, dp);
int notTake = f(i - 1, j, s, t, dp);
return dp[i][j] = take + notTake;
}
int reduce = f(i - 1, j, s, t, dp);
return dp[i][j] = reduce;
}
public:
int numDistinct(string s, string t)
{
int n = s.size(), m = t.size();
vector<vector<double>> dp(n, vector<double>(m, -1));
return f(n - 1, m - 1, s, t, dp);
}
};
class Solution {
int f(int i, int j, string& s, string& t, vector<vector<double>>& dp)
{
if (j == 0) return 1;
if (i == 0) return 0;
if (dp[i][j] != -1) return dp[i][j];
if (s[i - 1] == t[j - 1]) {
int take = f(i - 1, j - 1, s, t, dp);
int notTake = f(i - 1, j, s, t, dp);
return dp[i][j] = take + notTake;
}
int reduce = f(i - 1, j, s, t, dp);
return dp[i][j] = reduce;
}
public:
int numDistinct(string s, string t)
{
int n = s.size(), m = t.size();
vector<vector<double>> dp(n + 1, vector<double>(m + 1, -1));
return f(n, m, s, t, dp);
}
};
class Solution {
public:
int numDistinct(string s, string t)
{
int n = s.size();
int m = t.size();
vector<vector<double>> dp(n + 1, vector<double>(m + 1, 0));
for (int i = 0; i <= n; i++) {
dp[i][0] = 1;
}
for (int i = 1; i <= n; i++) {
for (int j = m; j >= 1; j--) { // both reverse and normal order works
if (s[i - 1] == t[j - 1]) {
dp[i][j] = dp[i - 1][j - 1] + dp[i - 1][j];
} else {
dp[i][j] = dp[i - 1][j];
}
}
}
return (int)dp[n][m];
}
};
class Solution {
public:
int numDistinct(string s, string t)
{
int n = s.size(), m = t.size();
vector<double> prev(m + 1, 0), curr(m + 1, 0);
prev[0] = curr[0] = 1;
for (int i = 1; i <= n; i++) {
for (int j = m; j >= 1; j--) {
if (s[i - 1] == t[j - 1]) {
curr[j] = prev[j - 1] + prev[j];
} else {
curr[j] = prev[j];
}
}
prev = curr;
}
return (int)prev[m];
}
};
current[i] = prev[i] + prev[i-1]
, so instead for storing it into current[i]
we can store it as prev[i]
as we are not using prev[i]
in future(it will become prev[i+1]
for next iteration).class Solution {
public:
int numDistinct(string s, string t)
{
int n = s.size(), m = t.size();
vector<double> dp(m + 1, 0);
dp[0] = 1;
for (int i = 1; i <= n; i++) {
for (int j = m; j >= 1; j--) {
if (s[i - 1] == t[j - 1]) {
dp[j] = dp[j - 1] + dp[j];
}
}
}
return (int)dp[m];
}
};