1513. 仅含 1 的子串数

目录

统计二进制字符串中只含1的子字符串数目

题目描述

问题拆解

解题思路

解题方法

代码实现(Python)

示例说明

复杂度分析与比较

总结


统计二进制字符串中只含1的子字符串数目

题目描述

给定一个仅包含字符 '0''1' 的二进制字符串 s
求字符串中所有只由字符 '1' 组成的子字符串的数量。

由于答案可能非常大,最终结果需要对 109+710^9 + 7 取模后返回。


问题拆解

我们想知道字符串中包含的所有“只含 1 的子字符串”数量。例如:

  • 对字符串 "111",所有只含 1 的子串为:
    "1", "1", "1", "11", "11", "111",共6个。
  • 对字符串 "1011",只含 1 的子串为:
    "1" (索引0), "1" (索引2), "1" (索引3), "11" (索引2-3),共4个。

解题思路

核心思路是:

  • 连续的 1 可以构成许多只包含 1 的子串。

如果某段连续的 1 长度为 k,那么这段连续 1 所包含的只由 1 组成的子串总数是:

  • \frac{k \times (k + 1)}{2}

这是因为:

  • 长度为1的子串有 k 个(每个单独的 1)。
  • 长度为2的子串有 k - 1 个。
  • ...
  • 长度为k的子串有 1 个。

将这些相加,就是等差数列求和公式。


解题方法

遍历字符串:

  • 用一个变量 count 统计当前连续 1 的长度。
  • 每遇到一个 '1'count 加一,并将 count 加到结果中(因为当前连续的 1 会产生 count 个新的只含 1 的子串)。
  • 遇到 '0',则将 count 重置为 0。

此方法时间复杂度为 O(n),空间复杂度为 O(1),非常高效。


代码实现(Python)

class Solution:
    def numSub(self, s: str) -> int:
        MOD = 10**9 + 7
        count = 0  # 当前连续1的长度
        result = 0

        for char in s:
            if char == '1':
                count += 1
                result = (result + count) % MOD
            else:
                count = 0

        return result

示例说明

举个具体例子说明:

s = "110111"

  • 遍历到索引0,字符为 '1'count=1,结果result=1
  • 索引1,字符 '1'count=2,结果result=1+2=3
  • 索引2,字符 '0'count=0,结果result=3
  • 索引3,字符 '1'count=1,结果result=3+1=4
  • 索引4,字符 '1'count=2,结果result=4+2=6
  • 索引5,字符 '1'count=3,结果result=6+3=9

最终结果是9,即:

只含1的子串包括:

  • "1" (0), "1" (1), "11" (0-1)
  • "1" (3), "1" (4), "1" (5), "11" (3-4), "11" (4-5), "111" (3-5)

复杂度分析与比较

方法

时间复杂度

空间复杂度

说明

直接枚举所有子串

O(n^2)

O(1)

超时,不适合大规模数据

连续1计数累加方法

O(n)

O(1)

高效且简洁,最优解


总结

本题核心是识别连续 1 的长度并利用等差数列求和公式高效计算子串数目。通过简单的线性扫描和计数,即可在 O(n) 时间内得到结果。

该方法简洁且避免了暴力枚举的超时问题,适合大规模字符串。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值