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
i
th
character (0-indexed) oftarget
, you can choose thek
th
character of thej
th
string inwords
iftarget[i] = words[j][k]
. - Once you use the
k
th
character of thej
th
string ofwords
, you can no longer use thex
th
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.
Python:
from typing import List
class Solution:
def numWays(self, words: List[str], target: str) -> int:
MOD = 10 ** 9 + 7
n, m = len(words[0]), len(target)
dp = [0] * (m+1)
count = [[0] * 5 for _ in range(n)]
dp[0] = 1
for i in range(n):
for word in words:
count[i][ord(word[i]) - ord('a')] += 1
for i in range(n):
for j in range(m-1, -1, -1):
dp[j+1] += dp[j] * count[i][ord(target[j]) - ord('a')]
dp[j+1] %= MOD
return dp[-1] % MOD
from collections import defaultdict
class Solution(object):
MOD = 10**9+7
def numWays(self, words, target):
word_len = len(words[0])
histograms= [defaultdict(int) for _ in range(word_len)]
for word in words:
for i, c in enumerate(word):
histograms[i][c] += 1
previous_dp = [1] * (word_len+1)
for target_idx, c in enumerate(target):
dp = [0] * (word_len+1)
remaining = len(target) - target_idx
for hist_idx in range(target_idx, word_len-remaining+1):
c_freq = histograms[hist_idx][c]
dp[hist_idx+1] = ((c_freq * previous_dp[hist_idx]) + dp[hist_idx]) % self.MOD
previous_dp = dp
return dp[-1]