统计满足 K 约束的子字符串数量-LeetCode
3258. 统计满足 K 约束的子字符串数量
🎯 问题描述(来源于LeetCode)
描述:
给定一个二进制字符串 s 和一个整数 k。
如果一个子串满足以下条件之一,则称该子串符合 K 约束:
- 子串中
0的个数不超过k; - 子串中
1的个数不超过k。
请返回符合 K 约束的子串总数。
说明:
- 子串是连续的。
- 字符串长度
1 <= s.length <= 50(对于本解法,滑动窗口可处理更大规模)。
示例:
- 示例 1:
1 | 输入: s = "10101", k = 1 |
- 示例 2:
1 | 输入: s = "1010101", k = 2 |
💻 解题思路
思路:滑动窗口(双指针)
算法步骤
- 将字符串转为数字列表,便于操作(
ch = [int(c) for c in s])。 - 初始化左指针
left = 0,计数器count = {0:0, 1:0},答案ans = 0。 - 遍历右指针
right,将当前字符ch[right]加入窗口计数。 - 当窗口内
0的个数和1的个数都大于k时,说明该窗口(以及以right为右端点且左端点更靠右的窗口)不满足条件,需要移动左指针缩小窗口,直到至少一类字符的个数 ≤k。- 将左指针指向的字符从计数中减去,左指针右移。
- 此时,以
right为右端点且左端点从left到right的所有子串都满足条件,数量为right - left + 1,累加到ans。 - 返回
ans。
代码实现
1 | from typing import List |
📊 性能分析
- 时间复杂度:,每个元素最多被左右指针各访问一次。
- 空间复杂度:,仅使用常数个变量。
思考
该解法利用滑动窗口维护当前窗口内 0 和 1 的数量,并在两者都超过 k 时收缩左边界。由于每次收缩后窗口一定满足条件,因此可以放心地累加以当前右端点结尾的所有子串数量。这是一种典型的统计满足条件的子串数量的技巧,比枚举所有子串更高效。代码简洁,逻辑清晰,是本题的标准解法。
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来源 笺札!






