Given two strings s and t, return the number of distinct subsequences of s which equals t.
"ACE" is a subsequence of "ABCDE").1 ≤ s.length, t.length ≤ 1000s and t consist of English letters.At each index of s, we need to decide what to do with the current character to build the target string t. We can model this as a tree of decisions:
s[i]. We move i forward but keep j the same. This explores other occurrences of t[j] later in s.s[i] == t[j], we can choose to use this matching character. We move both i and j forward.(i, j) is simply the sum of the ways from these two choices.Using the logic above, we can write a pure recursive function dfs(i, j). We need robust base cases so our recursion can terminate correctly:
j == len(t): We have successfully matched all of string t. Return 1 (one valid way).i == len(s): We ran out of characters in s but still need more for t. Return 0.| Approach | Time Complexity | Space Complexity |
|---|---|---|
| Brute DFS | O(2^M) | O(M) |
The recursive tree will visit the same (i, j) pairs repeatedly. We can memoize the results of these subproblems in a hash map dp[(i, j)]. If we see a state again, we return the cached value.
| Approach | Time Complexity | Space Complexity |
|---|---|---|
| Top-Down DP | O(M × N) | O(M × N) |
We can convert this to an iterative 2D DP table. The table dimension is (len(s) + 1) × (len(t) + 1).
Initialize the first column (where t is empty) to 1. Iterate backwards. The transitions are exactly the same as our recursive logic.
| Approach | Time Complexity | Space Complexity |
|---|---|---|
| Bottom-Up DP | O(M × N) | O(M × N) |
Notice that in the 2D table approach, computing the current row dp[i] solely depends on the row immediately below it dp[i + 1]. We don't need to keep the entire M × N matrix in memory.
We can reduce the space complexity to O(N) by only maintaining a single 1D array of size N + 1. When building iteratively, we overwrite the previous row.
| Approach | Time Complexity | Space Complexity |
|---|---|---|
| 1D Optimal DP | O(M × N) | O(N) |
Watch the algorithms in real-time execution. Switch tabs to see different approaches.
Discussion
…