Input: word1 ="bcca", word2 ="abc"Output: 1Explanation:
The only valid substring is`"bcca"` which can be rearranged to `"abcc"`having `"abc"` as a prefix.
We want to count all substrings of word1 that can be rearranged to have word2 as a prefix. For this, the substring must have at least as many of each character as in word2. To achieve linear time, we use a sliding window of length len(word2) and a hash of the frequency difference between the window and word2.
classSolution {
public:longlong countValidSubstrings(string word1, string word2) {
int n = word1.size(), m = word2.size();
vector<int> need(26, 0);
for (char c : word2) need[c -'a']++;
vector<int> cnt(26, 0);
longlong ans =0;
int valid =0;
for (int i =0; i < m && i < n; ++i) {
cnt[word1[i] -'a']++;
}
auto check = [&]() {
for (int i =0; i <26; ++i) if (cnt[i] < need[i]) return false;
return true;
};
if (n >= m && check()) ans++;
for (int l =1, r = m; r < n; ++l, ++r) {
cnt[word1[l-1] -'a']--;
cnt[word1[r] -'a']++;
if (check()) ans++;
}
return ans;
}
};
classSolution {
publiclongcountValidSubstrings(String word1, String word2) {
int n = word1.length(), m = word2.length();
int[] need =newint[26];
for (char c : word2.toCharArray()) need[c -'a']++;
int[] cnt =newint[26];
for (int i = 0; i < m && i < n; ++i) cnt[word1.charAt(i) -'a']++;
long ans = 0;
booleancheck() {
for (int i = 0; i < 26; ++i) if (cnt[i]< need[i]) returnfalse;
returntrue;
}
if (n >= m && check()) ans++;
for (int l = 1, r = m; r < n; ++l, ++r) {
cnt[word1.charAt(l-1) -'a']--;
cnt[word1.charAt(r) -'a']++;
if (check()) ans++;
}
return ans;
}
}
classSolution {
funcountValidSubstrings(word1: String, word2: String): Long {
val n = word1.length
val m = word2.length
val need = IntArray(26)
for (c in word2) need[c - 'a']++val cnt = IntArray(26)
for (i in0 until minOf(m, n)) cnt[word1[i] - 'a']++var ans = 0Lfuncheck(): Boolean {
for (i in0..25) if (cnt[i] < need[i]) returnfalsereturntrue }
if (n >= m && check()) ans++var l = 1; var r = m
while (r < n) {
cnt[word1[l-1] - 'a']-- cnt[word1[r] - 'a']++if (check()) ans++ l++; r++ }
return ans
}
}
classSolution:
defcountValidSubstrings(self, word1: str, word2: str) -> int:
n, m = len(word1), len(word2)
need = [0] *26for c in word2:
need[ord(c) - ord('a')] +=1 cnt = [0] *26for i in range(min(m, n)):
cnt[ord(word1[i]) - ord('a')] +=1 ans =0defcheck():
for i in range(26):
if cnt[i] < need[i]:
returnFalsereturnTrueif n >= m and check():
ans +=1for l, r in zip(range(1, n-m+1), range(m, n)):
cnt[ord(word1[l-1]) - ord('a')] -=1 cnt[ord(word1[r]) - ord('a')] +=1if check():
ans +=1return ans
impl Solution {
pubfncount_valid_substrings(word1: String, word2: String) -> i64 {
let n = word1.len();
let m = word2.len();
let word1 = word1.as_bytes();
let word2 = word2.as_bytes();
letmut need =vec![0; 26];
for&c in word2.iter() {
need[(c -b'a') asusize] +=1;
}
letmut cnt =vec![0; 26];
for i in0..std::cmp::min(m, n) {
cnt[(word1[i] -b'a') asusize] +=1;
}
letmut ans =0i64;
let check =|| (0..26).all(|i| cnt[i] >= need[i]);
if n >= m && check() {
ans +=1;
}
for l in1..=n-m {
let r = l + m -1;
cnt[(word1[l-1] -b'a') asusize] -=1;
cnt[(word1[r] -b'a') asusize] +=1;
if check() {
ans +=1;
}
}
ans
}
}