一、题目
给定一个字符串 s
,计算具有相同数量0和1的非空(连续)子字符串的数量,并且这些子字符串中的所有0和所有1都是组合在一起的。
重复出现的子串要计算它们出现的次数。
示例 1 :
输入: "00110011" 输出: 6 解释: 有6个子串具有相同数量的连续1和0:“0011”,“01”,“1100”,“10”,“0011” 和 “01”。 请注意,一些重复出现的子串要计算它们出现的次数。 另外,“00110011”不是有效的子串,因为所有的0(和1)没有组合在一起。
示例 2 :
输入: "10101" 输出: 4 解释: 有4个子串:“10”,“01”,“10”,“01”,它们具有相同数量的连续1和0。
注意:
s.length
在1到50,000之间。s
只包含“0”或“1”字符。
二、题解思路
- 题解思路1:多次遍历字符串,第一次遍历,看子字符串长度为2的情况,是否存在这样的子字符串;第二次遍历,看子字符串长度为4的情况.....;........,发现这样计算严重超时(不可取,说明有时候暴力破解是不行的)。
- 题解思路2:参考别人的想法,遍历字符串,将遍历过程中出现相同数字的个数存入数组,然后遍历数组,相邻两个值取最小的值,叠加求和即为满足要求的子串的个数、例如:1100100:数组中存的长度为2、2、1、2,相邻两个取最小:min(2,2)=2 (因为对于1100来说存在两种满足要求的连续子串:10、1100)、min(2,1)=1,min(1,2)=1.故满足要求的子串总和为2+1+1=4,输出为4。
- 题解思路3:用last来记录之前一种字符的个数,cur来记录当前字符的个数,当last>=cur时,满足条件的子串计数变量自动加一。
三、代码实现
- C++代码实现题解思路1
class Solution {
public:
int countBinarySubstrings(string s)
{
int counts = 0;
int size_1 = s.size();
int counts1 = 2;
while(counts1 <= size_1)
{
int i = 0;
while(i+counts1-1<size_1)
{
string temp = s.substr(i,counts1); //从i位置开始,截取counts1个字符
int flag = 0;
for(int j = 0;j<counts1/2;j++)
{
if(temp[j] == temp[counts1-j]) //说明不是所有0和所有1都是组合在一起的
flag = 1;
}
if(flag == 0) //是所有0和所有1组合在一起,flag标志位没变,则获得一个满足要求的子串
counts++;
i++;
}
counts1 = counts1 +2;
}
return counts;
}
};
- C++代码实现题解思路2
class Solution {
public:
int countBinarySubstrings(string s)
{
vector<int> nums;
int counts = 1;
for(int i =0;i<s.size()-1;i++) //将0或1连出现的次数依次记下来
{
if(s[i] == s[i+1])
{
counts++;
if(i+1 == s.size()-1 && s[i+1] == s[i]) //最后一个字符和倒数第二个字符一样
nums.push_back(counts);
}
else
{
nums.push_back(counts);
counts = 1;
}
}
if(counts == 1) //如果最后一个字符不是和倒数第二个一样,则需要往数组中再存入一个1
nums.push_back(1);
int count_sum = 0;
for(int i = 0;i<nums.size()-1;i++)
{
count_sum += min(nums[i],nums[i+1]); //取相邻两个字符的最小值叠加入总和
}
return count_sum;
}
};
- C++代码实现题解思路3
class Solution {
public:
int countBinarySubstrings(string s)
{
int last = 0; //前一种字符的个数变量
int cur = 1; //当前字符的个数变量
int count = 0; //满足要求的子串个数
for(int i = 1;i<s.size();i++) //对于s长度为1的情况,直接不满足,然后直接不执行for循环
{
if(s[i]==s[i-1]) //当前的字符与前一个字符一样
{
cur++; //当前字符个数加1
}
else
{
last = cur; //将当前字符个数赋给last
cur = 1;
}
if(last >= cur)
count++;
}
return count;
}
};