1639. Number of Ways to Form a Target String Given a Dictionary
Description
You are given a list of strings of the same length words
and a string target
.
Your task is to form target
using the given words
under the following rules:
target
should be formed from left to right.- To form the
ith
character (0-indexed) oftarget
, you can choose thekth
character of thejth
string inwords
iftarget[i] = words[j][k]
. - Once you use the
kth
character of thejth
string ofwords
, you can no longer use thexth
character of any string inwords
wherex <= k
. In other words, all characters to the left of or at indexk
become unusuable for every string. - Repeat the process until you form the string
target
.
Notice that you can use multiple characters from the same string in words
provided the conditions above are met.
Return the number of ways to form target
from words
. Since the answer may be too large, return it modulo 109 + 7
.
Example 1:
Input: words = ["acca","bbbb","caca"], target = "aba" Output: 6 Explanation: There are 6 ways to form target. "aba" -> index 0 ("acca"), index 1 ("bbbb"), index 3 ("caca") "aba" -> index 0 ("acca"), index 2 ("bbbb"), index 3 ("caca") "aba" -> index 0 ("acca"), index 1 ("bbbb"), index 3 ("acca") "aba" -> index 0 ("acca"), index 2 ("bbbb"), index 3 ("acca") "aba" -> index 1 ("caca"), index 2 ("bbbb"), index 3 ("acca") "aba" -> index 1 ("caca"), index 2 ("bbbb"), index 3 ("caca")
Example 2:
Input: words = ["abba","baab"], target = "bab" Output: 4 Explanation: There are 4 ways to form target. "bab" -> index 0 ("baab"), index 1 ("baab"), index 2 ("abba") "bab" -> index 0 ("baab"), index 1 ("baab"), index 3 ("baab") "bab" -> index 0 ("baab"), index 2 ("baab"), index 3 ("baab") "bab" -> index 1 ("abba"), index 2 ("baab"), index 3 ("baab")
Constraints:
1 <= words.length <= 1000
1 <= words[i].length <= 1000
- All strings in
words
have the same length. 1 <= target.length <= 1000
words[i]
andtarget
contain only lowercase English letters.
Solutions
Solution: Dynamic Programming
- Time complexity: O(words.length*m+mn)
- Space complexity: O(mn)
JavaScript
js
/**
* @param {string[]} words
* @param {string} target
* @return {number}
*/
const numWays = function (words, target) {
const m = words[0].length;
const n = target.length;
const MODULO = BigInt(10 ** 9 + 7);
const BASE_CODE = 'a'.charCodeAt(0);
const charCounts = Array.from({ length: m }, () => new Array(26).fill(0n));
const dp = Array.from({ length: m }, () => new Array(n).fill(-1));
for (const word of words) {
for (let index = 0; index < m; index++) {
const code = word[index].charCodeAt(0) - BASE_CODE;
charCounts[index][code] += 1n;
}
}
const getFormedCount = (wordIndex, targetIndex) => {
if (targetIndex >= n) return 1n;
if (wordIndex >= m || m - wordIndex < n - targetIndex) return 0n;
if (dp[wordIndex][targetIndex] !== -1) return dp[wordIndex][targetIndex];
const targetCode = target[targetIndex].charCodeAt(0) - BASE_CODE;
const charCount = charCounts[wordIndex][targetCode];
let result = getFormedCount(wordIndex + 1, targetIndex);
if (charCount) {
const count = charCount * getFormedCount(wordIndex + 1, targetIndex + 1);
result = (result + count) % MODULO;
}
dp[wordIndex][targetIndex] = result;
return result;
};
return Number(getFormedCount(0, 0));
};