力扣刷题记录
枚举 双指针
3258. 统计满足 K 约束的子字符串数量 I
思路
先是直接枚举子串的长度,然后再枚举子串的起点终点 判断满足要求的所有子串即可,时间复杂度会很高,但是这题的用例也可以过
双指针的思路 枚举右端点 统计个数
如果个数都超过了k 则移动左端点
以 r 为右端点的合法子串,其左端点可以是 l … l+1 … r
一共是 r - l + 1个加入到答案中
代码
class Solution {
public int countKConstraintSubstrings(String s, int k) {
// int res = 0;
// for(int len = 1; len <= s.length(); len ++){
// // 遍历子串是否满足条件
// for (int l = 0; l < s.length() - len + 1; l++){
// // 遍历子串的起点
// int left = l , right = l + len;
// int cnt0 = 0, cnt1 = 0;
// while (left < right){
// // 起点为left 终点为right - 1
// if (s.charAt(left) == '1'){
// cnt1 ++;
// }else{
// cnt0 ++;
// }
// left ++;
// }
// if (cnt0 <= k || cnt1 <= k){
// res ++;
// }
// }
// }
// return res;
int res = 0, cnt0 = 0, cnt1 = 0, l = 0, r = 0;
while (r < s.length()){
// 判断右边界
if (s.charAt(r) == '1'){
cnt1 ++;
}else{
cnt0 ++;
}
while (cnt0 > k && cnt1 > k){
// 当前右边界加入进来会超过k 因此需要移动左边界
if (s.charAt(l) == '1'){
cnt1 --;
}else{
cnt0 --;
}
l ++;
}
// 以 r 为右端点的合法子串,其左端点可以是 l .. l+1 .... r
// 一共是 r - l + 1个加入到答案中
res += r - l + 1;
r ++;
}
return res;
}
}
时间复杂度:O(n)
空间复杂度:O(1)