1. Recursive Suffix Matching
Intuition
At each index pair (i, j), if s[i] == t[j], branch into matching and skipping; otherwise skip s[i].
Algorithm
- Define
dfs(i, j). - If
j == t.length, return 1 (matched entire string t). - If
i == s.length, return 0 (s exhausted before matching t). - If
s[i] == t[j]: returndfs(i + 1, j + 1) + dfs(i + 1, j). - Else: return
dfs(i + 1, j).
#include <iostream>#include <string> using namespace std; int dfs(int i, int j, const string& s, const string& t) { if (j == (int)t.length()) return 1; if (i == (int)s.length()) return 0; if (s[i] == t[j]) { return dfs(i + 1, j + 1, s, t) + dfs(i + 1, j, s, t); } else { return dfs(i + 1, j, s, t); }} int numDistinctRec(string s, string t) { return dfs(0, 0, s, t);} int main() { string s = "rabbbit", t = "rabbit"; cout << "Distinct Subsequences (Recursive): " << numDistinctRec(s, t) << endl; return 0;}Time & Space Complexity
- Time complexity:
O(2^|s|) - Space complexity:
O(|s|) call stack