【LeetCode刷题日记】统计同构子字符串的数目题解

163 阅读4分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第32天,点击查看活动详情

✨欢迎关注🖱点赞🎀收藏⭐留言✒

🔮本文由京与旧铺原创,csdn首发!

😘系列专栏:算法学习

💻首发时间:🎞2022年12月26日🎠

🀄如果觉得博主的文章还不错的话,请三连支持一下博主哦

🎧作者是一个新人,在很多方面还做的不好,欢迎大佬指正,一起学习哦,冲冲冲


⭐️1759. 统计同构子字符串的数目⭐️

🔐题目详情

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 由小写字符串组成

💡解题思路

解题思路:

这道题目的意思很简单,就是求字符串中同构字符串的个数,我们先来理解什么是同构字符串,根据题目所给的定义:同构字符串定义为如果一个字符串中的所有字符都相同,那么该字符串就是同构字符串。 对于aaaaaaaaa等就是同构字符串。

我们需要求出一个字符串中所有同构字符串的数目,注意不是求同构字符串种类数,而是总数,即求字符串的所有子串中同构字符串的数目,根据同构字符串所有字母都相同的特点,我们只需遍历连续子字符串就可以了,就比如题目所给的栗子"abbcccaa"

1

我们可以从前往后遍历,依次找出所有的同构字符串,模拟一遍即可,但是这样做会超时。

1 代码如下(java):

class Solution {
    private static final int MOD = (int) 1e9 + 7;
    public int countHomogenous(String s) {
        //模拟
        char[] cs = s.toCharArray();
        int ans = 0;
        
        for (int i = 0; i < cs.length; i++) {
            ans++;
            int j = i + 1;
            while (j < cs.length && cs[j] == cs[i]) {
                ans++;
                j++;
            }
            ans = ans % MOD;
        }
        return ans;
    }
}

所以我们需要优化,由于同构字符串都是相同字母,因此我们只需要找相同字母的最长子串即可,在相同字母的子串中,可以拆分多个连续子串,这些子串全部也是同构字符串。 2 对于找到的每一个最长连续同构字符串,我们可以计算出该字符串所贡献的同构字符串的个数。

最长同构字符串a(长度为1)贡献的同构子串数目为1个。 最长同构字符串bb(长度为2)贡献的同构子串数目为1+2=3个。 最长同构字符串ccc(长度为3)贡献的同构子串数目为1+2+3=6个。 ... 那么不难推出最长同构字符串(长度为nn)贡献的同构子串数目为1+2+3+...+n=n(1+n)/21+2+3+...+n=n*(1+n)/2个。 1

🔑源代码

Java代码:

class Solution {
    private static final int MOD = (int) 1e9 + 7;
    public int countHomogenous(String s) {
        //模拟+等差数列
        char[] cs = s.toCharArray();
        long ans = 0;
        
        for (int i = 0; i < cs.length; i++) {
            int j = i + 1;
            while (j < cs.length && cs[j] == cs[i]) {
                j++;
            }
            int n = j - i;
            //对于n长度的同字母字符串 它的同构字符串数目为1+2+3+...+n=n(1+n)/2
            ans += (long) (1 + n) * n / 2;
            i = j - 1;
            ans %= MOD;
        }
        return (int) ans;
    }
}

C++版本代码:

const int MOD = (int) 1e9 + 7;
class Solution {
public:
    int countHomogenous(string s) {
        long ans = 0;
        for (int i = 0; i < s.length(); i++)
        {
            int j = i + 1;
            while (j < s.length() && s[j] == s[j - 1]) j++;

            int n = j - i;
            ans += (long) n * (1 + n) / 2;
            ans %= MOD;
            i = j - 1;
        }
        return (int) ans;
    }
};

C语言:

const int MOD = (int) 1e9 + 7;
int countHomogenous(char * s){
    long ans = 0;
    for (int i = 0; s[i] != '\0'; i++)
    {
        int j = i + 1;
        while (s[j] != '\0' && s[j] == s[j - 1]) j++;

        int n = j - i;
        ans += (long) n * (1 + n) / 2;
        ans %= MOD;
        i = j - 1;
    }
    return ans;
}

🌱总结

本题为简单模拟题,加了一丢丢数学找规律。