Skip to content
On this page

696. 计数二进制子串

原题链接:LeetCode 696. 计数二进制子串

题目描述

给定一个字符串 s,统计并返回具有相同数量 01 的非空(连续)子字符串的数量,并且这些子字符串中的所有 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;
};

技术文档集合