comments | difficulty | edit_url | rating | source | tags | |||
---|---|---|---|---|---|---|---|---|
true |
Hard |
1909 |
Weekly Contest 416 Q4 |
|
You are given two strings word1
and word2
.
A string x
is called valid if x
can be rearranged to have word2
as a prefix.
Return the total number of valid substrings of word1
.
Note that the memory limits in this problem are smaller than usual, so you must implement a solution with a linear runtime complexity.
Example 1:
Input: word1 = "bcca", word2 = "abc"
Output: 1
Explanation:
The only valid substring is "bcca"
which can be rearranged to "abcc"
having "abc"
as a prefix.
Example 2:
Input: word1 = "abcabc", word2 = "abc"
Output: 10
Explanation:
All the substrings except substrings of size 1 and size 2 are valid.
Example 3:
Input: word1 = "abcabc", word2 = "aaabc"
Output: 0
Constraints:
1 <= word1.length <= 106
1 <= word2.length <= 104
word1
andword2
consist only of lowercase English letters.
The problem is essentially to find how many substrings in
First, if the length of
Next, we use a hash table or an array of length
We then use a sliding window
We traverse each character in
After traversing all characters in
The time complexity is
class Solution:
def validSubstringCount(self, word1: str, word2: str) -> int:
if len(word1) < len(word2):
return 0
cnt = Counter(word2)
need = len(cnt)
ans = l = 0
win = Counter()
for c in word1:
win[c] += 1
if win[c] == cnt[c]:
need -= 1
while need == 0:
if win[word1[l]] == cnt[word1[l]]:
need += 1
win[word1[l]] -= 1
l += 1
ans += l
return ans
class Solution {
public long validSubstringCount(String word1, String word2) {
if (word1.length() < word2.length()) {
return 0;
}
int[] cnt = new int[26];
int need = 0;
for (int i = 0; i < word2.length(); ++i) {
if (++cnt[word2.charAt(i) - 'a'] == 1) {
++need;
}
}
long ans = 0;
int[] win = new int[26];
for (int l = 0, r = 0; r < word1.length(); ++r) {
int c = word1.charAt(r) - 'a';
if (++win[c] == cnt[c]) {
--need;
}
while (need == 0) {
c = word1.charAt(l) - 'a';
if (win[c] == cnt[c]) {
++need;
}
--win[c];
++l;
}
ans += l;
}
return ans;
}
}
class Solution {
public:
long long validSubstringCount(string word1, string word2) {
if (word1.size() < word2.size()) {
return 0;
}
int cnt[26]{};
int need = 0;
for (char& c : word2) {
if (++cnt[c - 'a'] == 1) {
++need;
}
}
long long ans = 0;
int win[26]{};
int l = 0;
for (char& c : word1) {
int i = c - 'a';
if (++win[i] == cnt[i]) {
--need;
}
while (need == 0) {
i = word1[l] - 'a';
if (win[i] == cnt[i]) {
++need;
}
--win[i];
++l;
}
ans += l;
}
return ans;
}
};
func validSubstringCount(word1 string, word2 string) (ans int64) {
if len(word1) < len(word2) {
return 0
}
cnt := [26]int{}
need := 0
for _, c := range word2 {
cnt[c-'a']++
if cnt[c-'a'] == 1 {
need++
}
}
win := [26]int{}
l := 0
for _, c := range word1 {
i := int(c - 'a')
win[i]++
if win[i] == cnt[i] {
need--
}
for need == 0 {
i = int(word1[l] - 'a')
if win[i] == cnt[i] {
need++
}
win[i]--
l++
}
ans += int64(l)
}
return
}
function validSubstringCount(word1: string, word2: string): number {
if (word1.length < word2.length) {
return 0;
}
const cnt: number[] = Array(26).fill(0);
let need: number = 0;
for (const c of word2) {
if (++cnt[c.charCodeAt(0) - 97] === 1) {
++need;
}
}
const win: number[] = Array(26).fill(0);
let [ans, l] = [0, 0];
for (const c of word1) {
const i = c.charCodeAt(0) - 97;
if (++win[i] === cnt[i]) {
--need;
}
while (need === 0) {
const j = word1[l].charCodeAt(0) - 97;
if (win[j] === cnt[j]) {
++need;
}
--win[j];
++l;
}
ans += l;
}
return ans;
}