给你一个字符串 s
,它只包含三种字符 a, b 和 c 。
请你返回 a,b 和 c 都 至少 出现过一次的子字符串数目。
示例 1:
输入:s = "abcabc" 输出:10 解释:包含 a,b 和 c 各至少一次的子字符串为 "abc", "abca", "abcab", "abcabc", "bca", "bcab", "bcabc", "cab", "cabc" 和 "abc" (相同字符串算多次)。
示例 2:
输入:s = "aaacb" 输出:3 解释:包含 a,b 和 c 各至少一次的子字符串为 "aaacb", "aacb" 和 "acb" 。
示例 3:
输入:s = "abc" 输出:1
提示:
3 <= s.length <= 5 x 10^4
s
只包含字符 a,b 和 c 。
设置一个滑框count用于存a,b,c是否存在 当我们从start开始遍历当时我们遍历到abc都存在的时候此时已start为开头的数量就是s.lenght()-此时的下标比如
s=“abcabc" 当第一次abc存在时那么已下标0开头的情况数量就是s.lenght()-c的下标2;
class Solution {
public int numberOfSubstrings(String s) {
int answer=0;
//abc 的计数
int[] count=new int[3];
//窗口左沿
int start=0;
//窗口右沿
for(int end=0;end<s.length();end++){
char charAtEnd=s.charAt(end);
count[charAtEnd-'a']++;
while(count[0]>=1 && count[1]>=1 && count[2]>=1){
//answer用于存储总数,s.length()-end就是当前以start开头的剩余的情况数量
answer+=s.length()-end;
/*当进入while循环时已经意为着找到了以start开头的所有情况所以要将count中代表start开头的字母删除并将start加1代表从下一个开始*/
char charAtStart=s.charAt(start);
count[charAtStart-'a']--;
start++;
}
}
return answer;
}
}