判断两个字符串s和t,s的子串中能够包含t中所有字符的子串数
我的解法:
其实也就是求word1中包含word2中所有字符的子串数
class Solution {
public long validSubstringCount(String word1, String word2) {
if (word1.length() < word2.length()) {
return 0;
}
long res = 0;
//记录两个字符串中字符的数量
int[] record1 = new int[26];
int[] record2 = new int[26];
//统计word2中每个字符出现的次数
for(char c : word2.toCharArray()) {
record2[c - 'a']++;
}
int chartypes = 0;
//统计word2中字符的种类,用来记录在滑动窗口移动时子串中包含的字符种类符合word2要求
for (int i : record2) {
if (i != 0) {
chartypes++;
}
}
char[] s = word1.toCharArray();
// int l, r;
for (int l = 0, r = 0; r < s.length; r++) {
char c = s[r];
record1[c - 'a']++;
//子串中c字符的数量满足word2的需求
if (record1[c - 'a'] == record2[c - 'a']) {
chartypes--;
}
//每种字符的数量都满足要求了
if (chartypes == 0) {
res += s.length - r;
//左移窗口直到不满足word2的需求
while (record1[s[l] - 'a'] == 0 || record1[s[l] - 'a'] > record2[s[l] - 'a']) {
if (record1[s[l] - 'a'] != 0) {
record1[s[l] - 'a']--;
}
res += s.length - r;
l++;
}
record1[s[l] - 'a']--;
l++;
chartypes++;
}
}
return res;
}
}
**灵神方法:**也可以创建一个数组进行滑动窗口
class Solution {
public long validSubstringCount(String S, String T) {
if (S.length() < T.length()) {
return 0;
}
char[] s = S.toCharArray();
char[] t = T.toCharArray();
int[] cnt = new int[26]; // t 的字母出现次数与 s 的字母出现次数之差
for (char b : t) {
cnt[b - 'a']++;
}
int less = 0; // 统计窗口内有多少个字母的出现次数比 t 的少
for (int c : cnt) {
if (c > 0) {
less++;
}
}
long ans = 0;
int left = 0;
for (char b : s) {
if (--cnt[b - 'a'] == 0) {
// 窗口内 b 的出现次数和 t 一样
less--;
}
while (less == 0) { // 窗口符合要求
if (cnt[s[left++] - 'a']++ == 0) {
// s[left] 移出窗口后,窗口内 s[left] 的出现次数比 t 的少
less++;
}
}
ans += left;
}
return ans;
}
}