Problem
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 10^9 + 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
class Solution {
private static final int MOD = (int) 1e9 + 7;
public int numWays(String[] words, String target) {
int[][] counts = precompute(words);
Integer[][] memo = new Integer[target.length()][words[0].length()];
return solve(memo, counts, words, target, 0, 0);
}
private int[][] precompute(String[] words) {
int[][] counts = new int[words[0].length()][26];
for (String word : words) {
for (int idx = 0; idx < word.length(); idx++) {
counts[idx][word.charAt(idx) - 'a']++;
}
}
return counts;
}
private int solve(
Integer[][] memo, int[][] counts, String[] words, String target, int idx, int len) {
if (idx >= target.length()) {
return 1;
}
if (len >= words[0].length() || words[0].length() - len < target.length() - idx) {
return 0;
}
if (memo[idx][len] != null) {
return memo[idx][len];
}
int answer = 0;
answer += solve(memo, counts, words, target, idx, len + 1);
answer %= MOD;
answer +=
(int)
((long) solve(memo, counts, words, target, idx + 1, len + 1)
* counts[len][target.charAt(idx) - 'a']
% MOD);
answer %= MOD;
memo[idx][len] = answer;
return memo[idx][len];
}
}
Explain:
nope.
Complexity:
- Time complexity : O(n).
- Space complexity : O(n).