一、题目
Leetcode 3258题:
给你一个 二进制 字符串 s 和一个整数 k。
如果一个 二进制字符串 满足以下任一条件,
则认为该字符串满足 k 约束:
1. 字符串中 0 的数量最多为 k。
2. 字符串中 1 的数量最多为 k。
返回一个整数,表示 s 的所有满足 k 约束
的子字符串的数量。
二、输入
s 和 k
三、输出
返回一个整数,表示 s 的所有满足 k 约束
的子字符串的数量。
四、示例
示例一
输入:
s = "10101", k = 1
输出:
12
- 解释:s 的所有子字符串中,除了 “1010”、“10101” 和 “0101” 外,其余子字符串都满足 k 约束。
示例二
输入:
s = "1010101", k = 2
输出:
25
五、题解
- 这题是 LeetCode 简单题,实际做起来不简单
- 先理解题意子字符串是连续的,满足任一个最多 K 个字符的条件
- 一开始往排列组合集合方向想就复杂了
- 暴力方法是两重遍历,参考下面 Java 解法
- 优化的方法是滑动窗口,参考下面的 Python 解法。统计方法是针对每一个右边界位置,在满足题目条件时,累加符合条件的左边界字符个数,也就是
right - left + 1
5.1 Java 实现
class Solution {
public int countKConstraintSubstrings(String s, int k) {
int n = s.length();
int ans = 0;
for(int i = 0; i < n; i++) {
int[] cnt = new int[2];
cnt[0] = 0;
cnt[1] = 0;
for(int j = i; j < n; j++) {
cnt[s.charAt(j) - '0']++;
if(cnt[0] > k && cnt[1] > k) {
break;
}
++ans;
}
}
return ans;
}
}
5.2 Python实现
class Solution:
def countKConstraintSubstrings(self, s: str, k: int) -> int:
ans, left = 0, 0
cnt = [0, 0]
for right, c in enumerate(s):
cnt[int(c)] += 1
while cnt[0] > k and cnt[1] > k:
cnt[int(s[left])] -= 1
left += 1
# 以right为右边界返回子字符串的个数
ans += (right - left + 1)
return ans
obj = Solution()
ans = obj.countKConstraintSubstrings("10101", 1)
# 12
print(ans)
ans = obj.countKConstraintSubstrings("1010101", 2)
# 25
print(ans)
ans = obj.countKConstraintSubstrings("11111", 1)
# 15
print(ans)