开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第35天,点击查看活动详情
给你一个字符串 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 <= 10^5s由小写字符串组成
思路
首先我们先看看如何求一个同构字符串的字串个数,假设同构字符串为'aaaaa',字串'a'出现了5次,'aa'出现了4次,'aaa'出现了3次,'aaaa'出现了2次,'aaaaa'出现了1次,总计字串个数为5 + 4 + 3 + 2 + 1 = 15次。设一个同构字串长度为n,他的字串个数为
n + (n - 1) + (n - 2) + ... + 2 + 1 = (n + 1) * n / 2。
我们可以遍历字符串s,求出所有的同构字符串,再求这些同构字符串的字串个数。用same表示同构字符串的长度,用i表示当前字符下标,
- 当
s[i]===s[i-1]时,表示当前字符属于当前同构字符串,same++。 - 当
s[i]===s[i-1]时,表示当前字符不属于当前同构字符串,计算当前同构字符串字串个数。same = 1,开始一个新的同构字符串。
解题
/**
* @param {string} s
* @return {number}
*/
var countHomogenous = function (s) {
const MOD = 10 ** 9 + 7;
const n = s.length;
let same = 1;
let res = 0;
for (let i = 1; i <= n; i++) {
if (s[i] != s[i - 1]) {
res = (res + ((1 + same) * same) / 2) % MOD;
same = 1;
} else {
same++;
}
}
return res;
};