1.暴力法
子字符串中的0或1需要连续,
对于***0001111***,增加的数量为连续0,连续1的最小值,如此处会增加000111,0011,01三个,恰好等于连续0的数量
挨个遍历,若当前元素是0,寻找其后连续0,连续1的个数,总数增加min(连续0,连续1)
若当前元素为1,寻找其后连续1,连续0的个数,总数增加min(连续1,连续0)的个数
代码如下:
class Solution {
public:
int countBinarySubstrings(string s) {
//子字符串中0的数量和1得到数量相等,且子字符串中的0或1都是挨着的
//000111 有3个,00111有2个
int count=0;
int len=s.size();
int start=0;
while(start<len)
{
int i=start;
if(s[i]=='0')
{
int count1=0;
int count2=0;
while(s[i]=='0')
{
i++;
count1++;
}
while(s[i]=='1')
{
i++;
count2++;
}
count+=min(count1,count2);
start+=count1;
}
else if(s[i]=='1')
{
int count3=0;
int count4=0;
while(s[i]=='1')
{
i++;
count3++;
}
while(s[i]=='0')
{
i++;
count4++;
}
count+=min(count3,count4);
start+=count3;
}
}
return count;
}
};
2.优化
可以发现上述方法在当前元素为0或者1的时候内部的处理很相似,我们可以使用last记录上一个连续0或者1的个数,cur表示当前连续0或者1的个数,
初始令last=0,cur=1
若当前元素和其之前的元素相等,则cur++
若当前元素与前一个元素不等,则更新last,令last=cur,cur=1,
若last>=cur,则总数自增1
如00011000
初始last=0,cur=1
s[1]=s[0],cur++=2;s[2]=s[1],cur++=3;
s[3]!=s[2],last=3,cur=1;此时last>cur,则res++=1,新增的位s[2]s[3],即01
s[4]=s[3],cur++=2;此时last>cur,则res++=2;新增的为s[1]s[2]s[3]s[4],即0011
s[5]!=s[4],令last=2,cur=1;此时last>cur,则res++=3,新增的为s[4]s[5],即10
s[6]=s[5],cur++=2;此时last==cur,则res++=4,新增的为s[3]s[4]s[5]s[6],即1100
代码如下:
class Solution {
public:
int countBinarySubstrings(string s) {
//子字符串中0的数量和1得到数量相等,且子字符串中的0或1都是挨着的
//000111 有3个,00111有2个
int count=0;
int len=s.size();
int last=0,cur=1;
for(int i=1;i<len;i++)
{
if(s[i]==s[i-1])
cur++;
else
{
last=cur;
cur=1;
}
if(last>=cur)
count++;
}
return count;
}
};