一、问题描述

二、解题思路
解法一:暴力枚举+优化
最容易想到的办法是使用2个for循环进行暴力枚举,但是在这个基础上,我们可以进行优化。固定子字符的起点,若此时已经满足条件,则后续字符无需再完成遍历,直接用ret+=(s.size()-j)即可。
解法二:滑动窗口
由于子数组连续且可以做到指针不回退,所以,可以使用滑动窗口来解决这个问题。
三、代码实现
解法一:暴力枚举+优化(超时)
cpp
class Solution {
public:
int numberOfSubstrings(string s) {
//暴力+优化
int ret=0;
for(int i=0;i!=s.size();i++){
map<char,int> hash;
int count=0;
for(int j=i;j!=s.size();j++){
char in=s[j];
hash[in]++;
if(hash[in]==1) count++;
if(count==3) {
ret+=(s.size()-j);
break;
}
}
}
return ret;
}
};
解法二:滑动窗口
cpp
class Solution {
public:
int numberOfSubstrings(string s) {
//滑动窗口
map<char,int> hash;int count=0;
int ret=0;
for(int left=0,right=0;right!=s.size()&&count!=3;right++){
//进窗口
char in=s[right];hash[in]++;
if(hash[in]==1) count++;
//出窗口
while(count==3){
ret+=s.size()-right;
char out=s[left++];
hash[out]--;
if(hash[out]==0) count--;
}
}
return ret;
}
};