题意:
给你一个由小写字母组成的长度为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;
}
};
时间复杂度:
空间复杂度:![]()



京公网安备 11010502036488号