目标
给定一个字符串 s,统计并返回具有相同数量 0 和 1 的非空(连续)子字符串的数量,并且这些子字符串中的所有 0 和所有 1 都是成组连续的。
重复出现(不同位置)的子串也要统计它们出现的次数。
示例 1:
输入:s = "00110011"
输出:6
解释:6 个子串满足具有相同数量的连续 1 和 0 :"0011"、"01"、"1100"、"10"、"0011" 和 "01" 。
注意,一些重复出现的子串(不同位置)要统计它们出现的次数。
另外,"00110011" 不是有效的子串,因为所有的 0(还有 1 )没有组合在一起。
示例 2:
输入:s = "10101"
输出:4
解释:有 4 个子串:"10"、"01"、"10"、"01" ,具有相同数量的连续 1 和 0 。
说明:
- 1 <= s.length <= 10^5
- s[i] 为 '0' 或 '1'
思路
统计二进制字符串 s 中满足条件的子串个数。子串需满足 0 与 1 的个数相等,且子串中所有 0 都是相邻且连续的(由于数量相同,子串中所有的 1 也是相邻且连续的),即 0 与 1 都是成组连续的。
00011 满足条件的子串个数为 min(3, 2),可以分组循环字符串,记录前一组的个数,累加二者最小值即可。
代码
/**
* @date 2026-02-24 16:14
*/
public class CountBinarySubstrings696 {
public int countBinarySubstrings(String s) {
char[] chars = s.toCharArray();
int n = chars.length;
int preCnt = 0;
int i = 0;
int res = 0;
while (i < n) {
int start = i;
while (i < n && chars[start] == chars[i]) {
i++;
}
int cnt = i - start;
res += Math.min(preCnt, cnt);
preCnt = cnt;
}
return res;
}
}
性能
