Number of Ways to Form a Target String Given a Dictionary

Count ways to form target by picking one char from each column-position of `words` — 2D DP.

Hard
Time O(L * |target| + L * 26) Space O(|target|)
LeetCode
4 min read
dp

Problem#

words are strings of equal length. To form target, pick target[i] from column c_i of words such that c_0 < c_1 < ... < c_{|target|-1}. Return the count mod 10⁹+7.

Examples#

  • words = ["acca","bbbb","caca"], target = "aba"6

Constraints#

  • 1 <= len(words) <= 1000, len(target) <= 1000.

Approach#

Precompute freq[c][col] = count of letter c at column col. Let dp[j] = ways to match target[:j]. For each column left-to-right, update from high j to low: dp[j] += dp[j - 1] * freq[target[j - 1]][col].

Solution#

Form Target From Dictionary
class Solution {
public:
int numWays(vector<string>& words, string target) {
const int MOD = 1'000'000'007;
int L = words[0].size(), T = target.size();
vector<vector<int>> freq(26, vector<int>(L, 0));
for (auto& w : words)
for (int c = 0; c < L; ++c)
++freq[w[c] - 'a'][c];
vector<long long> dp(T + 1, 0);
dp[0] = 1;
for (int c = 0; c < L; ++c) {
for (int j = T; j >= 1; --j) {
dp[j] = (dp[j] + dp[j - 1] * freq[target[j - 1] - 'a'][c]) % MOD;
}
}
return (int)dp[T];
}
};

Editorial#

The 2D DP dp[j][c] = ways to match target[:j] using columns up to c; transition either skips column c or uses it for target[j]. Rolling along columns and updating j ↓ is the standard 0/1-knapsack-style reduction.

Complexity#

  • Time: O(L * T + L * 26).
  • Space: O(T).

Concept revision#

Search ESC

Keyboard shortcuts

Shortcuts are disabled while typing in inputs.