题目描述
给定一个字符串 s
,返回 s
中 同构子字符串 的数目。由于答案可能很大,只需返回对 10^9 + 7
取余 后的结果。
同构字符串 的定义为:如果一个字符串中的所有字符都相同,那么该字符串就是同构字符串。
子字符串 是字符串中的一个连续字符序列。
样例
输入: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
输入:s = "xy"
输出:2
解释:同构子字符串是 "x" 和 "y" 。
输入:s = "zzzzz"
输出:15
限制
1 <= s.length <= 10^5
s
由小写字符串组成。
算法
(双指针,数学) $O(n)$
- 找到所有极大的同构字符串。
- 对于一个极大的同构字符串,其包含的同构字符串的个数为 $len \cdot (len - 1) / 2$。
时间复杂度
- 遍历字符串一次,故总时间复杂度为 $O(n)$。
空间复杂度
- 仅需要常数的额外空间。
C++ 代码
#define LL long long
class Solution {
public:
int countHomogenous(string s) {
const int mod = 1000000007;
const int n = s.size();
int last = 0;
int ans = 0;
for (int i = 1; i < n; i++) {
if (s[i] == s[i - 1]) continue;
ans = (ans + (LL)(i - last) * (i - last + 1) / 2) % mod;
last = i;
}
return (ans + (LL)(n - last) * (n - last + 1) / 2) % mod;
}
};