115. Distinct Subsequences
Difficulty: Hard
Topics: String, Dynamic Programming
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.
rabbbitrabbbitrabbbit
Example 2:
- Input: s = "babgbag", t = "bag"
- Output: 5
-
Explanation:
- As shown below, there are 5 ways you can generate "bag" from s.
babgbagbabgbagbabgbagbabgbagbabgbag
Example 3:
- Input: s = "a", t = "a"
- Output: 1
Example 4:
- Input: s = "a", t = "b"
- Output: 0
Example 5:
- Input: s = "aaa", t = "aa"
- Output: 3
Example 6:
- Input: s = "abc", t = ""
- Output: 1
Example 7:
- Input: s = "abcd", t = "abcd"
- Output: 1
Example 8:
- Input: s = "abcd", t = "ac"
- Output: 1
Example 9:
- Input: s = "abab", t = "ab"
- Output: 3
Example 10:
- Input: s = "xxx", t = "xx"
- Output: 3
Constraints:
1 <= s.length, t.length <= 1000-
sandtconsist of English letters.
Solution:
We solve the "Distinct Subsequences" problem using a space-optimized dynamic programming approach. We iterate through each character of s and update a 1D DP array that tracks the number of ways to form prefixes of t. By processing t backwards, we ensure that each character of s is used at most once per subsequence, resulting in an efficient O(m*n) time and O(n) space solution.
Approach
- Use a DP array
dpwheredp[j]represents the number of distinct subsequences of the processed prefix ofsthat equal the firstjcharacters oft. - Initialize
dp[0] = 1because there is exactly one way to form an empty subsequence (choose no characters). - Iterate through each character
cins(from left to right). - For each character, iterate
jfromndown to1(backwards) to prevent reuse of the currentscharacter multiple times in the same update. - If
cmatchest[j-1], thendp[j] += dp[j-1]because we can either skipc(keep old value) or use it to extend subsequences that already matcht[0..j-2]. - After processing all characters of
s,dp[n]holds the total number of distinct subsequences equal tot.
Let's implement this solution in PHP: 115. Distinct Subsequences
<?php
/**
* @param String $s
* @param String $t
* @return Integer
*/
function numDistinct(string $s, string $t): int
{
...
...
...
/**
* go to ./solution.php
*/
}
// Test cases
echo numDistinct("rabbbit", "rabbit") . "\n"; // Output: 3
echo numDistinct("babgbag", "bag") . "\n"; // Output: 5
echo numDistinct("a", "a") . "\n"; // Output: 1
echo numDistinct("a", "b") . "\n"; // Output: 0
echo numDistinct("aaa", "aa") . "\n"; // Output: 3
echo numDistinct("abc", "") . "\n"; // Output: 1
echo numDistinct("abcd", "abcd") . "\n"; // Output: 1
echo numDistinct("abcd", "ac") . "\n"; // Output: 1
echo numDistinct("abab", "ab") . "\n"; // Output: 3
echo numDistinct("xxx", "xx") . "\n"; // Output: 3
?>
Explanation:
-
Base case:
dp[0] = 1ensures that matching the first character oftstarts from a valid count. -
Backward traversal: Prevents using the same
s[i]multiple times for different positions intwithin the same iteration. -
Transition: When
s[i-1] == t[j-1], we add the number of ways to formt[0..j-2]using previous characters ofs(dp[j-1]) to the current count fort[0..j-1]. -
Skip case: The old
dp[j]already accounts for not usings[i-1], so we don’t need to explicitly copy it. -
Result: After all characters,
dp[n]gives the answer, which fits in a 32-bit integer per constraints.
Complexity Analysis
-
Time Complexity: O(m * n), where
m= length ofsandn= length oft. We process each character ofsand update allnpositions oft. -
Space Complexity: O(n), using a single 1D array of size
n+1instead of a full 2D matrix.
Contact Links
If you found this series helpful, please consider giving the repository a star on GitHub or sharing the post on your favorite social networks 😍. Your support would mean a lot to me!

If you want more helpful content like this, feel free to follow me:
Top comments (0)