1639. Number of Ways to Form a Target String Given a Dictionary
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.
Solution 1: Preprocessing + Memory Search
Solution 2: Preprocessing + Dynamic Programming
C++
class Solution { public: int numWays(vector<string>& words, string target) { const int mod = 1e9 + 7; int m = target.size(), n = words[0].size(); vector<vector<int>> cnt(n, vector<int>(26)); for (auto& w : words) { for (int j = 0; j < n; ++j) { ++cnt[j][w[j] - 'a']; } } int f[m][n]; memset(f, -1, sizeof(f)); function<int(int, int)> dfs = [&](int i, int j) -> int { if (i >= m) { return 1; } if (j >= n) { return 0; } if (f[i][j] != -1) { return f[i][j]; } int ans = dfs(i, j + 1); ans = (ans + 1LL * dfs(i + 1, j + 1) * cnt[j][target[i] - 'a']) % mod; return f[i][j] = ans; }; return dfs(0, 0); } };
JAVA
class Solution { private int m; private int n; private String target; private Integer[][] f; private int[][] cnt; private final int mod = (int) 1e9 + 7; public int numWays(String[] words, String target) { m = target.length(); n = words[0].length(); f = new Integer[m][n]; this.target = target; cnt = new int[n][26]; for (var w : words) { for (int j = 0; j < n; ++j) { cnt[j][w.charAt(j) - 'a']++; } } return dfs(0, 0); } private int dfs(int i, int j) { if (i >= m) { return 1; } if (j >= n) { return 0; } if (f[i][j] != null) { return f[i][j]; } long ans = dfs(i, j + 1); ans += 1L * dfs(i + 1, j + 1) * cnt[j][target.charAt(i) - 'a']; ans %= mod; return f[i][j] = (int) ans; } }
PYTHON
class Solution { public: int numWays(vector<string>& words, string target) { const int mod = 1e9 + 7; int m = target.size(), n = words[0].size(); vector<vector<int>> cnt(n, vector<int>(26)); for (auto& w : words) { for (int j = 0; j < n; ++j) { ++cnt[j][w[j] - 'a']; } } int f[m][n]; memset(f, -1, sizeof(f)); function<int(int, int)> dfs = [&](int i, int j) -> int { if (i >= m) { return 1; } if (j >= n) { return 0; } if (f[i][j] != -1) { return f[i][j]; } int ans = dfs(i, j + 1); ans = (ans + 1LL * dfs(i + 1, j + 1) * cnt[j][target[i] - 'a']) % mod; return f[i][j] = ans; }; return dfs(0, 0); } };
Comments
Post a Comment