【LeetCode】1759. 统计同构子字符串的数目

统计同构子字符串的数目


题目描述

给你一个字符串 s ,返回 s 中 同构子字符串 的数目。由于答案可能很大,只需返回对 109 + 7 取余 后的结果。

同构字符串 的定义为:如果一个字符串中的所有字符都相同,那么该字符串就是同构字符串。

子字符串 是字符串中的一个连续字符序列。


示例 1

输入:s = “abbcccaa”
输出:13
解释:同构子字符串如下所列:
“a” 出现 3 次。
“aa” 出现 1 次。
“b” 出现 2 次。
“bb” 出现 1 次。
“c” 出现 3 次。
“cc” 出现 2 次。
“ccc” 出现 1 次。
3 + 1 + 2 + 1 + 3 + 2 + 1 = 13


示例 2

输入:s = “xy”
输出:2
解释:同构子字符串是 “x” 和 “y” 。


示例 3

输入:s = “zzzzz”
输出:15


提示

  • 1 <= s.length <= 105
  • s 由小写字符串组成

算法一:模拟+数学

思路

  • 首先,单个字符一定是同构字符串,因此 res 一开始被赋值为 len
  • 接下来,遍历每个字符,判断它与随后的字符是否会构成同构字符串。如果当前字符s[i] == s[j],说明存在同构字符串,否则不存在,继续判断下一个字符。那么如何计算同构字符串的个数呢?
  • 我们先看一个例子: “cccc” ,其中包含的同构字符串有:c:4, cc:3, ccc:2, cccc:1,不难发现,假设连续字符串的个数为 cnt ,那么同构字符串的个数为:cnt * (cnt + 1) / 2 ,由于单个字符串(即 ‘c’ 的情况),我们一开始就计入了,因此同构字符串的个数为:cnt * ( cnt - 1) / 2
  • 在实现中,我令 ans 从 0 开始,也就是说,如果 “cc” ,则 ans = 1 ,那么此时的同构字符串个数为:ans * (ans + 1) / 2 。至于为什么令 ans 的初值为0,方便判断此时是否存在连续字符串。

收获

  • 此题不难,刚好昨天做的题运用了数学思想,因此很快想到了 i*(i+1)/2
  • 一开始不通过的原因是:mod=1e9+7 ,我写成了 mod=10e9+7

算法情况

  • 时间复杂度:O(n),其中 n 为字符串长度。
  • 空间复杂度:O(1)
    在这里插入图片描述

代码

class Solution {
public:
    int countHomogenous(string s) {
        int len = s.size();
        long long mod = 1e9 + 7;
        // 单个字符即为一个同构字符串
        long long res = (long long)len;
        for(int i=0; i<len; ++i){
            int ans = 0;
            for(int j=i+1; j<len; ++j){
                if(s[j] == s[i])    ans ++;
                else break;
            }
            if(ans){
                res += (long long)(ans+1) * ans / 2;
                i += ans;
            }
        }
        return res%mod;
    }
};
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值