LeetCode 696计数二进制子串Easy
-
题目简述:给定一个字符串
s
,计算具有相同数量0和1的非空(连续)子字符串的数量,并且这些子字符串中的所有0和所有1都是组合在一起的。重复出现的子串要计算它们出现的次数。s.length
在1到50,000之间。s
只包含“0”或“1”字符。 -
题目本质: 统计二进制字符串中连续 1 和连续 0 数量相同的子字符串个数
-
输入:“00110011” 输出:6 解释:有6个子串:01,10,01,0011,1100,0011它们具有相同数量的连续1和0。011001不是有效子串,因为所有的0和1没有连续
输入:“10101” 输出:4 解释:有4个子串:10,01,10,01,它们具有相同数量的连续1和0。
-
思路:中心扩展法,暴力遍历字符串,分别以01和10为中心向两侧扩展,适用于小数据,时间复杂度O(n2)
class Solution {
public:
int cnt = 0;
void extendSubstrings(string s, int l, int r)
{
char sl = s[l];
char sr = s[r];
while(l >= 0 && r < s.size() && s[l] == sl && s[r] == sr)
{
l--;
r++;
cnt++;
}
}
int countBinarySubstrings(string s) {
for(int i = 1; i < s.size(); i++)
{
if(s[i - 1] == '0' && s[i] == '1')
{
extendSubstrings(s, i - 1, i);
}
if(s[i - 1] == '1' && s[i] == '0')
{
extendSubstrings(s, i - 1, i);
}
}
return cnt;
}
};
-
思路二:满足要求的字符串不会存在0和1混合的情况,比如0101,1010
例如:输入0011,那么输出为2
- 0,cur = 1, pre = 0,cnt = 0
- 0,cur = 2, pre = 0,cnt = 0
- 1,cur = 1, pre = 2,cnt = 1//答案为001中的01
- 1,cur = 2, pre = 2,cnt = 2//答案为0011中的0011
class Solution {
public:
int countBinarySubstrings(string s) {
int cnt = 0; // 满足要求的子串的个数
int pre = 0; // 前一个字符出现的次数
int cur = 1; // 当前的字符出现的次数
for(int i = 1; i < s.size(); i++)
{
if(s[i] == s[i - 1])
cur++;
else
{
pre = cur;//出现了不同的字符就更新前一个字符出现次数
cur = 1;
}
// 前一个字符个数 >= 当前字符个数时,就找到一个答案
if(pre >= cur)
cnt++;
}
return cnt;
}
};