统计同构子字符串的数目

165 阅读2分钟

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

1759. 统计同构子字符串的数目 - 力扣(LeetCode)

给你一个字符串 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^5
  • s 由小写字符串组成

思路

首先我们先看看如何求一个同构字符串的字串个数,假设同构字符串为'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;
};