Leetcode696. 计数二进制子串(字符串, 字串)

链接:https://leetcode-cn.com/problems/count-binary-substrings
给定一个字符串 s,计算具有相同数量0和1的非空(连续)子字符串的数量,并且这些子字符串中的所有0和所有1都是组合在一起的。
重复出现的子串要计算它们出现的次数。

示例 1 :

输入: "00110011"
输出: 6
解释:6个子串具有相同数量的连续10:“0011”,“01”,“1100”,“10”,“0011” 和 “01”。
请注意,一些重复出现的子串要计算它们出现的次数。
另外,“00110011”不是有效的子串,因为所有的0(和1)没有组合在一起。

示例 2 :

输入: "10101"
输出: 4
解释:4个子串:“10”,“01”,“10”,“01”,它们具有相同数量的连续10

注意:

s.length 在150,000之间。
s 只包含“0”或“1”字符。

最终改进代码如下:

/* 思路
遍历字符串记录以下几个值
count    查找到的子串个数
count0   当前查找到的连续 0 个数, 用完置 0 
count1   当前查找到的连续 1 个数, 用完置 0
group0   当前查找到的连续 0 的组数, 用完置 0 (1 正常情况)
group1   当前查找到的连续 1 的组数, 用完置 0 (1 正常情况)

改进, 上述方法需要区分第一个数字为 0 或者为 1
countf  counts   groupf   groups  
f-firsr    当前字符串第一个字符类型
s-second   当前字符串第二个字符类型

*/
int countBinarySubstrings(char * s){
    int count = 0;
    int countf = 0;
    int counts = 0;
    int groupf = 0;
    int groups = 0;
    
    char *cur = s;
    while(*cur != '\0'){  // 该层遍历整个字符串
        while(*cur != '\0'){  // 该层遍历当前查找子串
            if(*cur == *s){
                if(0 == groups){ groupf = 1; }
                if(1 == groups){ 
                    count+=counts; 
                    s+=countf; 
                    cur = s; 
                    break; 
                }
                countf++; // 改进, 之前放在该段if 之前
            }else{
                counts++;
                groups = 1;
                if(counts == countf){ 
                    count+=countf; 
                    s+=countf; 
                    cur = s; 
                    break; 
                }
            }
            cur++;
        }

        if(*cur == '\0'){s++;  cur = s;} // 特殊情况,cur 查到了最后。
        countf = 0;
        counts = 0;
        groupf = 0;
        groups = 0;
    }

    return count;
}

版本–改进超出时间限制问题:

int countBinarySubstrings(char * s){
    int count = 0;
    int count0 = 0;
    int count1 = 0;
    int group0 = 0;
    int group1 = 0;
    
    char *cur = s;
    while(*cur != '\0'){
        char frist_c = *s;
        
        if(frist_c == '0'){
            while(*cur != '\0'){
                if(*cur == '0'){
                    count0++;
                    if(0 == group1){ group0 = 1; }
                    if(1 == group1){ count0--; count+=count1; s+=count0; cur = s; break; }
                }
                if(*cur == '1'){
                    count1++;
                    group1 = 1;
                    if(count1 == count0){ count+=count0; s+=count0; cur = s; break; }
                }
                cur++;
            }
        }

        if(frist_c == '1'){
            while(*cur != '\0'){
                if(*cur == '1'){
                    count1++;
                    if(0 == group0){ group1 = 1; }
                    if(1 == group0){ count1--; count+=count0; s+=count1; cur = s; break; }
                }
                if(*cur == '0'){
                    count0++;
                    group0 = 1;
                    if(count0 == count1){ count+=count1; s+=count1; cur = s; break; }
                }
                cur++;
            }
        }

        if(*cur == '\0'){s++;  cur = s;}
        count0 = 0;
        count1 = 0;
        group0 = 0;
        group1 = 0;
    }

    return count;
}

版本–暴力破解(超出时间限制):

int countBinarySubstrings(char * s){
    int count = 0;
    int count0 = 0;
    int count1 = 0;
    int group0 = 0;
    int group1 = 0;
    
    char *cur = s;
    while(*cur != '\0'){
        char frist_c = *s;
        
        if(frist_c == '0'){
            while(group0 <= 1 && group1 <=1 && *cur != '\0'){
                if(*cur == '0'){
                    count0++;
                    if(0 == group1){ group0 = 1; }
                    if(1 == group1){ group0++; break; }
                }
                if(*cur == '1'){
                    count1++;
                    group1 = 1;
                    if(count1 == count0){ count++; break; }
                }
                cur++;
            }
            cur = ++s;
            count0 = 0;
            count1 = 0;
            group0 = 0;
            group1 = 0;
        }

        if(frist_c == '1'){
            while(group1 <= 1 && group0 <=1 && *cur != '\0'){
                if(*cur == '1'){
                    count1++;
                    if(0 == group0){ group1 = 1; }
                    if(1 == group0){ group1++; break; }
                }
                if(*cur == '0'){
                    count0++;
                    group0 = 1;
                    if(count0 == count1){ count++; break; }
                }
                cur++;
            }
            cur = ++s;
            count0 = 0;
            count1 = 0;
            group0 = 0;
            group1 = 0;
        }
    }

    return count;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值