2023-04-16 Daily Challenge
Today I have done leetcode's April LeetCoding Challenge with cpp
.
April LeetCoding Challenge 16
Description
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
auto speedup = [](){
cin.tie(nullptr);
cout.tie(nullptr);
ios::sync_with_stdio(false);
return 0;
}();
class Solution {
const int MOD = 1e9 + 7;
public:
int numWays(vector<string>& words, string target) {
int wordLen = words.front().length();
int targetLen = target.length();
if(targetLen > wordLen) return 0;
vector<vector<int>> count(26, vector<int>(wordLen + 1));
for(const auto &word : words) {
for(int i = 0; i < wordLen; ++i) {
count[word[i] - 'a'][i] += 1;
}
}
for(int c = 0; c < 26; ++c) {
for(int i = wordLen - 1; i >= 0; --i) {
count[c][i] += count[c][i + 1];
}
}
vector<vector<int>> dp(wordLen + 1, vector<int>(targetLen, -1));
function<int(int, int)> solve = [&](int wordPos, int targetPos) {
if(targetPos == targetLen) return 1;
if(dp[wordPos][targetPos] != -1) return dp[wordPos][targetPos];
int c = target[targetPos] - 'a';
long long result = 0;
int originalPos = wordPos;
for(int pos = wordPos; count[c][pos] && wordLen - pos >= targetLen - targetPos; ++pos) {
if(count[c][pos] - count[c][pos + 1]) {
result += 1LL * (count[c][pos] - count[c][pos + 1]) * solve(pos + 1, targetPos + 1);
result %= MOD;
}
}
dp[wordPos][targetPos] = result;
return dp[wordPos][targetPos];
};
// solve(0, 0);
// cout << count << endl;
// cout << dp << endl;
// return dp[0][0];
return solve(0, 0);
}
};
// Accepted
// 89/89 cases passed (760 ms)
// Your runtime beats 5.18 % of cpp submissions
// Your memory usage beats 48.28 % of cpp submissions (53.8 MB)