[LeetCode] Count Binary Substrings 统计二进制子字符串

 

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.html

Substrings that occur multiple times are counted the number of times they occur.java

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:post

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:url

  • s.length will be between 1 and 50,000.
  • s will only consist of "0" or "1" characters.

 

这道题给了咱们一个二进制字符串,而后咱们统计具备相同0和1的个数,且0和1各自都群组在一块儿(即0和1不能交替出现)的子字符串的个数,题目中的两个例子也很能说明问题。那么咱们来分析题目中的第一个例子00110011,符合要求的子字符串要求0和1同时出现,那么当第一个1出现的时候,前面因为前面有两个0,因此确定能组成01,再遇到下一个1时,此时1有2个,0有2个,能组成0011,下一个遇到0时,此时0的个数重置为1,而1的个数有两个,因此必定有10,同理,下一个还为0,就会有1100存在,以后的也是这样分析。那么咱们能够发现咱们只要分别统计0和1的个数,并且若是当前遇到的是1,那么只要以前统计的0的个数大于当前1的个数,就必定有一个对应的子字符串,而一旦前一个数字和当前的数字不同的时候,那么当前数字的计数要重置为1。因此咱们遍历元数组,若是是第一个数字,那么对应的ones或zeros自增1。而后进行分状况讨论,若是当前数字是1,而后判断若是前面的数字也是1,则ones自增1,不然ones重置为1。若是此时zeros大于ones,res自增1。反之同理,若是当前数字是0,而后判断若是前面的数字也是0,则zeros自增1,不然zeros重置为1。若是此时ones大于zeros,res自增1。参见代码以下:spa

 

解法一:code

class Solution {
public:
    int countBinarySubstrings(string s) {
        int zeros = 0, ones = 0, res = 0;
        for (int i = 0; i < s.size(); ++i) {
            if (i == 0) {
                (s[i] == '1') ? ++ones : ++zeros;
            } else {
                if (s[i] == '1') {
                    ones = (s[i - 1] == '1') ? ones + 1 : 1;
                    if (zeros >= ones) ++res;
                } else if (s[i] == '0') {
                    zeros = (s[i - 1] == '0') ? zeros + 1 : 1;
                    if (ones >= zeros) ++res;
                }
            }
        }
        return res;
    }
};

 

下面这种方法更加简洁了,不用具体的分0和1的状况来讨论了,而是直接用了pre和cur两个变量,其中pre初始化为0,cur初始化为1,而后从第二个数字开始遍历,若是当前数字和前面的数字相同,则cur自增1,不然pre赋值为cur,cur重置1。而后判断若是pre大于等于cur,res自增1。其实核心思想跟上面的方法同样,只不过pre和cur能够在0和1之间切换,参见代码以下:htm

 

解法二:blog

class Solution {
public:
    int countBinarySubstrings(string s) {
        int res = 0, pre = 0, cur = 1, n = s.size();
        for (int i = 1; i < n; ++i) {
            if (s[i] == s[i - 1]) ++cur;
            else {
                pre = cur;
                cur = 1;
            }
            if (pre >= cur) ++res;
        }
        return res;
    }
};

 

相似题目:ip

Encode and Decode Strings

 

参考资料:

https://discuss.leetcode.com/topic/107096/java-o-n-time-o-1-space

 

LeetCode All in One 题目讲解汇总(持续更新中...)

相关文章
相关标签/搜索