696. Count Binary Substrings

1.问题描诉

Give a string s, count the number of non-empty (contiguous) substrings that have the same number of 0’s and 1’s, and all the 0’s and all the 1’s in these substrings are grouped consecutively.
Substrings that occur multiple times are counted the number of times they occur.
Example 1:
Input: “00110011”
Output: 6
Explanation: There are 6 substrings that have equal number of consecutive 1’s and 0’s: “0011”, “01”, “1100”, “10”, “0011”, and “01”.
Notice that some of these substrings repeat and are counted the number of times they occur.
Also, “00110011” is not a valid substring because all the 0’s (and 1’s) are not grouped together.
Example 2:
Input: “10101”
Output: 4
Explanation: There are 4 substrings: “10”, “01”, “10”, “01” that have equal number of consecutive 1’s and 0’s.
Note:
• s.length will be between 1 and 50,000.
• s will only consist of “0” or “1” characters.

来自 https://leetcode.com/problems/count-binary-substrings/description/

2.题目分析:

给出一个字符串s,计算具有相同数字0和1的非空(连续)子字符串的数量,并且将这些子字符串中的全部0和全部1连续分组。多次出现的子串被统计为它们发生的次数。通过观察发现,“000111”中有01,0011,000111,共3个;“000011111”,中有01,0011,000111,00001111,共4个;存在的规律:将字符串分成若干段,每一段都是0…01….1;这样的形式,那么这些段中满足的条件子串的个数为较小的连续0或者1的个数,比如00111111,这一段,0的个数最少为2,因此存在满足条件的子串01,0011共2个。那么这道题解决的方法就变成了,计算连续0或者1的个数,并存入数组,最后对数组进行两两比较,将较小数进行求和即可。
这里写图片描述

3.C++代码

//我的代码:(beats 42%)
int countBinarySubstrings(string s)
{
    int L = s.length();
    int left = 0;
    int right = 0;
    vector<int>a;
    while (left < L&&right < L)
    {
        char c = s[left];
        while (s[right] == c&&right < L)
            right++;
        a.push_back(right - left);
        left = right;
    }
    int sum = 0;
    for (int i = 1; i < a.size(); i++)
    {
        if (a[i] > a[i - 1])
            sum += a[i - 1];
        else
            sum += a[i];
    }
    return sum;
}

分析上面的方法:计算出连续01的长度数组后,再遍历数组求和,这个过程其实可以在求长度的时候顺便求和了,方法如下;

//改进后的:(beats 97%)
int countBinarySubstrings2(string s)
{
    int L = s.length();
    int left = 0;
    int right = 0;
    int x1 = 0;
    int sum = 0;
    while (left < L&&right < L)
    {
        char c = s[left];
        while (s[right] == c&&right < L)
            right++;
        if (x1 < right - left)
            sum += x1;
        else
            sum += (right - left);

        x1 = right - left;//更新
        left = right;
    }
    return sum;
}

猜你喜欢

转载自blog.csdn.net/qq_29689907/article/details/80380844
今日推荐