字符串:力扣696. 计数二进制子串

01、题目描述:

在这里插入图片描述

2、题解:

方法1:按字符分组:
思路:

注意审题:题目要求的是子串(连续),而不是子序列(未必连续)。且子串中的01的数量相等且相同的数字是连续的。
按照01的连续段进行分组,存于counts中,例如s = 00111011,那么counts = [2,3,1,2]
counts中相邻的数,一定是s中不同的数字。假设counts相邻的数字为u或v,那么构成满足条件的子串的
数目为min(u,v),这是对答案的贡献。
构建完counts数组后,只需要遍历counts数组,求所有min(u,v)之和即可

Python代码如下:

class Solution:
    def countBinarySubstrings(self, s: str) -> int:
        #按字符分组
        counts = []
        left,n = 0,len(s)
        while left < n:
            c = s[left]
            count = 0
            while left < n and s[left] == c:
                left += 1
                count += 1
            counts.append(count)
        res = 0
        for i in range(1,len(counts)):
            res += min(counts[i],counts[i-1])
        return res

方法2:优化:
我们发现求满足条件的答案时,counts数组中的该值,只与前一个值有关,即min(u,v),因此可以记录last是上一个counts值,来代替counts数组,优化空间。

class Solution:
    def countBinarySubstrings(self, s: str) -> int:
        #优化
        res = 0
        left,n = 0,len(s)
        last = 0
        while left < n:
            count = 0
            c = s[left]
            while left < n and c == s[left]:
                left += 1
                count += 1
            res += min(last,count)
            last = count
        return res

3、复杂度分析:

方法1:
时间复杂度:O(N)
空间复杂度:O(N)
方法2:
时间复杂度:O(N)
空间复杂度:O(1)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值