题意:
给你一个由小写字母组成的长度为n的字符串 S ,找出所有长度为 k 且包含重复字符的子串,请你返回全部满足要求的子串的数目。
方法一:
暴力模拟
思路:暴力枚举。
外层循环枚举起点,内层循环枚举长度为k的区间,并判断该区间是否包含重复字符。
class Solution { public: int cnt[26]={0};//计数数组 int numKLenSubstrRepeats(string s, int k) { int res=0; int len=s.size(); for(int i=0;i<len-k+1;i++){//枚举起点 memset(cnt,0,sizeof(cnt)); for(int j=i;j<i+k;j++){//遍历长度为k的区间 cnt[s[j]-'a']++; if(cnt[s[j]-'a']>1){//判断是否包含重复字符 res++; break; } } } return res; } };
时间复杂度:空间复杂度:
方法二:
滑动窗口
思路:利用左右指针(滑动窗口)实现。先初始化一个长度为 k 的区间,然后循环,左右指针每次加一,并判断区间内是否有包含重复字符的子串。
class Solution { public: int cnt[26]={0};//计数数组 int numKLenSubstrRepeats(string s, int k) { int res=0; int len=s.size(); int l=0,r=0;//左右指针 while(r<len){//循环条件 if(r<k){//初始化长度为k的区间 cnt[s[r++]-'a']++; }else{ for(int i=0;i<26;i++){//判断是否有包含重复字符的子串 if(cnt[i]>1){ res++; break; } } cnt[s[r++]-'a']++;//右指针++ cnt[s[l++]-'a']--;//左指针++ } } for(int i=0;i<26;i++){ if(cnt[i]>1){ res++; break; } } return res; } };
时间复杂度:空间复杂度: