leetcode 1358 包含所有三种字符的子字符数目

一、问题描述

二、解题思路

解法一:暴力枚举+优化

最容易想到的办法是使用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;
    }
};