1759. 统计同质子字符串的数目

目录

计算字符串中同质子字符串的数量 — 题解与思路分析

题目描述

什么是“同质子字符串”?

解题分析

关键点

为什么可以拆分成段来计算?

解题方法

思路步骤

代码实现(Python)

复杂度分析

示例说明

示例1

示例2

解法对比

总结


计算字符串中同质子字符串的数量 — 题解与思路分析


题目描述

给定一个字符串 s,计算其中所有同质子字符串的数量。

  • 同质字符串的定义是:字符串中所有字符都相同。
  • 子字符串是字符串中连续的一段字符序列。

由于答案可能非常大,只需返回对 109+710^9 + 7 取余后的结果。

示例

  • 输入:s = "abbcccaa"
  • 输出:13

什么是“同质子字符串”?

所谓“同质子字符串”,就是子字符串中的所有字符都相同。比如:

  • "a" 是同质字符串
  • "bb" 是同质字符串
  • "ccc" 是同质字符串
  • "ab" 不是(不同字符)
  • "aca" 不是(不同字符)

题目要求统计字符串中所有可能的同质子字符串个数。


解题分析

关键点

字符串是由多个连续字符组成的,我们要找到所有的连续且字符相同的子字符串。

观察字符串 s,可以将它拆分成若干段连续相同字符的区间:

例如:"abbcccaa"
分段为:"a", "bb", "ccc", "aa"

对于每一段长度为 n 的连续相同字符子串,它产生的同质子字符串数量为:

数量=1+2+3+…+n=n(n+1)2\text{数量} = 1 + 2 + 3 + \ldots + n = \frac{n(n+1)}{2}

这是因为:

  • 长度为1的子串有 n 个(每个字符单独的子串)
  • 长度为2的同质子串有 n-1
  • 长度为3的同质子串有 n-2
  • 长度为n的同质子串有 1

为什么可以拆分成段来计算?

因为不同连续段中的字符不相同,不可能组成同质子字符串跨段边界。

例如 "abbcccaa" 中,"bb""ccc" 是不同字符段,不可能组合成同质子字符串。


解题方法

思路步骤

  1. 初始化结果变量 res = 0,以及一个计数器 count = 1 用来记录当前连续段长度。
  2. 遍历字符串:
    • 如果当前字符和前一个字符相同,则 count += 1
    • 否则,说明当前连续段结束:
      • 计算当前段产生的同质子字符串数 count×(count+1)2\frac{count \times (count + 1)}{2},累加到 res
      • 重置 count = 1
  1. 遍历结束后,别忘记加上最后一段的贡献。
  2. 返回结果对 109+710^9 + 7 取余。

代码实现(Python)

class Solution:
    def countHomogenous(self, s: str) -> int:
        MOD = 10**9 + 7
        res = 0
        count = 1

        for i in range(1, len(s)):
            if s[i] == s[i - 1]:
                count += 1
            else:
                res += count * (count + 1) // 2
                count = 1

        # 加上最后一段的贡献
        res += count * (count + 1) // 2
        return res % MOD

复杂度分析

  • 时间复杂度:O(n)
    只需遍历字符串一次。
  • 空间复杂度:O(1)
    只使用了常数个额外变量。

示例说明

示例1

输入:"abbcccaa"

分段:

  • "a" 长度为1,贡献 1×(1+1)/2=11 \times (1+1)/2 = 1
  • "bb" 长度为2,贡献 2×3/2=32 \times 3/2 = 3
  • "ccc" 长度为3,贡献 3×4/2=63 \times 4/2 = 6
  • "aa" 长度为2,贡献 2×3/2=32 \times 3/2 = 3

总贡献:

1+3+6+3=131 + 3 + 6 + 3 = 13

输出:13


示例2

输入:"leetcode"

分析:

  • "l" 长度1,贡献1
  • "e" 长度1,贡献1
  • "e" 长度1,贡献1
  • "t" 长度1,贡献1
  • "c" 长度1,贡献1
  • "o" 长度1,贡献1
  • "d" 长度1,贡献1
  • "e" 长度1,贡献1

总贡献为8。


解法对比

  • 暴力法:遍历所有子字符串,检查是否同质,时间复杂度 O(n3)O(n^3) 或 O(n2)O(n^2),效率极低。
  • 本方法:利用连续段统计,时间复杂度仅为 O(n)O(n),极大提升了效率。

总结

本题关键在于识别字符串中连续的相同字符段,并利用数学公式快速计算同质子字符串数量。只需一次遍历即可完成计数,非常高效。此方法在处理类似题目时具有很好的推广价值。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值