Appearance
696. 计数二进制子串
题目描述
给定一个字符串 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 <= 105
- `s[i]` 为 `'0'` 或 `'1'`
难度: Easy
题解代码
javascript
/**
* @param {string} s
* @return {number}
*/
var countBinarySubstrings = function(s) {
// 这种方法耗时最长
// let r = []
// let count = 0
// let match = str => {
// let a = str.match(/^(0+|1+)/)[0]
// let b = `${a[0] ^ 1}`.repeat(a.length)
// str.startsWith(a + b) && count++
// }
// for (let i = 0, len = s.length; i < len; i++) {
// match(s.slice(i))
// }
// return count
// 这种方法速度第一
s += ' '; // 末尾加一个字符,方便处理尾巴边界问题
let prevLen = 0; // 上一个字符的总长
let curLen = 0; // 当前字符的总长
let charNow = s[0]; // 当前字符
let sum = 0; // 重复总次数
// 每次字符发生切换时,统计上一次重复的次数
for (let i = 0; i < s.length; i++) {
if (s[i] === charNow) {
curLen++;
} else {
// '00001110011'-->4,3,2,2, ==> 0+3+2+2===7
sum += Math.min(prevLen, curLen);
prevLen = curLen;
curLen = 1;
charNow = s[i];
}
}
return sum;
// 这种方法速度第二
// var res = [];
// let temp = s[0];
// let count=0;
// for(let i of s){
// if(i!==temp) {
// res.push(count);
// temp=i;
// count=0;
// }
// count++;
// }
// '00001110011'-->count === [4,3,2,2,] ==> 3+2+2===7
// res.push(count);
// count=0;
// for(let i=0;i<res.length-1;++i){
// count+= Math.min(res[i],res[i+1]);
// }
// return count;
};