python-leetcode-696. 计数二进制子串

696. 计数二进制子串 - 力扣(LeetCode)

可以使用 贪心双指针 来解决这个问题。核心思想是统计相邻的 0 组和 1 组的大小,并计算能形成的平衡子字符串数量。

解题思路:

  1. 统计相邻相同字符的长度

    • 遍历字符串 s,计算相邻字符相同的连续子串长度,存入 counts 数组。例如:

      s = "00110011"
      counts = [2, 2, 2, 2]
      

      这里 [2, 2] 代表 0011,后面 [2, 2] 代表 0011

  2. 计算有效的子串数量

    • 两个相邻的 counts[i]counts[i+1] 可以形成 min(counts[i], counts[i+1]) 个平衡子串。例如:

      • 0011 组合可以形成 min(2,2) = 20110 的子串。

代码实现:

def countBinarySubstrings(s: str) -> int:
    counts = []
    n = len(s)
    i = 0

    # 统计连续相同字符的长度
    while i < n:
        count = 1
        while i + 1 < n and s[i] == s[i + 1]:
            i += 1
            count += 1
        counts.append(count)
        i += 1

    # 计算相邻的 0 组和 1 组能形成的子字符串数量
    ans = 0
    for j in range(1, len(counts)):
        ans += min(counts[j - 1], counts[j])

    return ans

示例:

print(countBinarySubstrings("00110011"))  # 输出: 6
print(countBinarySubstrings("10101"))     # 输出: 4

复杂度分析:

  • 时间复杂度: O(n),因为我们遍历了 s 两次(一次构造 counts,一次计算答案)。

  • 空间复杂度: O(n),用于存储 counts 数组。

这种方法高效且容易理解,通过构造 counts 数组简化了问题。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值