InterviewPrepKit

Home / Coding / Algorithm & Data Structure / 2-D Dynamic Programming

Distinct Subsequences

hard Original ↗ 00:00

Problem

Given two strings s and t, count the number of distinct ways to delete some (possibly zero) characters from s, without reordering the rest, so that the remaining characters spell exactly t. Two ways are different if they delete a different set of positions. Return that count.

A subsequence keeps characters in their original order but need not be contiguous.

Examples

  • s = "rabbbit", t = "rabbit"3 — three different choices of which b to drop from the three b’s in s produce "rabbit".
  • s = "babgbag", t = "bag"5 — five distinct index-sets of s spell "bag".
  • s = "abc", t = "abcd"0t is longer than s, so it can never be formed.

Constraints

  • 1 <= len(s), len(t) <= 1000 (roughly)
  • Both strings consist of English letters.
  • The answer fits in a 32-bit signed integer.
  • With lengths up to ~1000, an O(len(s)·len(t)) table is the intended complexity; enumerating subsequences (up to 2^len(s)) is impossible.

Think about it first

Hint 1 Walk both strings from the front. Consider the last character of the prefixes you are matching. Whether `s`'s current character equals `t`'s current character decides your options.
Hint 2 Let `dp[i][j]` be the number of ways the first `j` characters of `t` appear as a subsequence of the first `i` characters of `s`. You can always *skip* `s[i-1]` (that gives `dp[i-1][j]`). If `s[i-1] == t[j-1]`, you may additionally *use* it to match `t[j-1]`, adding `dp[i-1][j-1]`.
Hint 3 `dp[i][j] = dp[i-1][j] + (dp[i-1][j-1] if s[i-1]==t[j-1] else 0)`. The base case `dp[i][0] = 1` (the empty `t` is matched exactly one way — delete everything). Since each row needs only the row above, one array of length `len(t)+1` swept right-to-left suffices.

Write your solution, then hit Run tests to check it — or get a mock grade from the AI coach.

The coach remembers this session — revise your code and ask again, and it grades your progress. It gives hints, not the answer.
Report a bug