Skip to content

2953. Count Complete Substrings

Description

You are given a string word and an integer k.

A substring s of word is complete if:

  • Each character in s occurs exactly k times.
  • The difference between two adjacent characters is at most 2. That is, for any two adjacent characters c1 and c2 in s, the absolute difference in their positions in the alphabet is at most 2.

Return the number of complete substrings of word.

A substring is a non-empty contiguous sequence of characters in a string.

 

Example 1:

Input: word = "igigee", k = 2
Output: 3
Explanation: The complete substrings where each character appears exactly twice and the difference between adjacent characters is at most 2 are: igigee, igigee, igigee.

Example 2:

Input: word = "aaabbbccc", k = 3
Output: 6
Explanation: The complete substrings where each character appears exactly three times and the difference between adjacent characters is at most 2 are: aaabbbccc, aaabbbccc, aaabbbccc, aaabbbccc, aaabbbccc, aaabbbccc.

 

Constraints:

  • 1 <= word.length <= 105
  • word consists only of lowercase English letters.
  • 1 <= k <= word.length

 

Solutions

Solution: Sliding Window + Hash Table

  • Time complexity: O(262n)
  • Space complexity: O(26 -> 1)

 

JavaScript

js
/**
 * @param {string} word
 * @param {number} k
 * @return {number}
 */
const countCompleteSubstrings = function (word, k) {
  const n = word.length;
  const BASE_CODE = 'a'.charCodeAt(0);
  const uniqueChars = new Set(word).size;
  let result = 0;

  const getCode = char => char.charCodeAt(0) - BASE_CODE;

  for (let len = k; len <= n && len <= uniqueChars * k; len += k) {
    const counts = new Array(26).fill(0);
    let chars = 0;

    for (let index = 0; index < n; index++) {
      const code = getCode(word[index]);
      const prevCode = index ? getCode(word[index - 1]) : code;

      if (Math.abs(code - prevCode) > 2) {
        counts.fill(0);
        chars = 0;
      }

      counts[code] += 1;
      chars += 1;

      if (chars > len) {
        const firstCode = getCode(word[index - len]);

        counts[firstCode] -= 1;
        chars -= 1;
      }

      if (chars === len && counts.every(count => count === k || !count)) {
        result += 1;
      }
    }
  }

  return result;
};

Released under the MIT license