**输入:** s = "xy"
**输出:** 2
**解释:** 同质子字符串是 "x" 和 "y" 。
示例 3:
**输入:** s = "zzzzz"
**输出:** 15
提示:
1 <= s.length <= 105
s 由小写字符串组成
方法一:数学
思路与算法
题目给出一个长度为 n 的字符串 s,并给出「同构字符串」的定义为:如果一个字符串中的所有字符都相同,那么该字符串就是同构字符串。现在我们需要求 s 中「同构子字符串」的数目。 因为「同构子字符串」为一个连续的字符序列且需要序列中的字符都相同,那么我们首先按照连续相同的字符来对字符串 s 进行分组,比如对于字符串 abbcccaa" 我们的分组结果为 [a”,bb",ccc”,``aa”]。因为对于一个组中字符串的任意子字符串都为「同构子字符串」,而一个长度为 m 的字符串的子字符串的数目为 \dfrac{m \times (m + 1)}{2。那么我们对于每一个组来统计其贡献的「同构子字符串」数目并求和即可。
代码
[sol1-Python3]
1 2 3 4 5 6 7
classSolution: defcountHomogenous(self, s: str) -> int: res = 0 for k, g in groupby(s): n = len(list(g)) res += (n + 1) * n // 2 return res % (10 ** 9 + 7)
classSolution { public: intcountHomogenous(string s){ longlong res = 0; longlong mod = 1e9 + 7; int prev = s[0]; int cnt = 0; for (auto c : s) { if (c == prev) { cnt++; } else { res += (longlong)(cnt + 1) * cnt / 2; cnt = 1; prev = c; } } res += (longlong)(cnt + 1) * cnt / 2; return res % mod; } };
[sol1-C]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
intcountHomogenous(char * s) { longlong res = 0; longlong mod = 1e9 + 7; int prev = s[0]; int cnt = 0; for (int i = 0; s[i] != '\0'; i++) { if (s[i] == prev) { cnt++; } else { res += (longlong)(cnt + 1) * cnt / 2; cnt = 1; prev = s[i]; } } res += (longlong)(cnt + 1) * cnt / 2; return res % mod; }
[sol1-JavaScript]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
var countHomogenous = function(s) { constMOD = 1000000007; let res = 0; let prev = s[0]; let cnt = 0; for (let i = 0; i < s.length; i++) { const c = s[i]; if (c === prev) { cnt++; } else { res += (cnt + 1) * cnt / 2; cnt = 1; prev = c; } } res += (cnt + 1) * cnt / 2; return res % MOD; };
[sol1-Golang]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
funccountHomogenous(s string) (res int) { const mod int = 1e9 + 7 prev := rune(s[0]) cnt := 0 for _, c := range s { if c == prev { cnt++ } else { res += (cnt + 1) * cnt / 2 cnt = 1 prev = c } } res += (cnt + 1) * cnt / 2 return res % mod }