LeetCode in Kotlin

2953. Count Complete Substrings

Hard

You are given a string word and an integer k.

A substring s of word is complete if:

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:

Solution

import kotlin.math.abs

class Solution {
    fun countCompleteSubstrings(word: String, k: Int): Int {
        val arr = word.toCharArray()
        val n = arr.size
        var result = 0
        var last = 0
        for (i in 1..n) {
            if (i == n || abs((arr[i].code - arr[i - 1].code).toDouble()) > 2) {
                result += getCount(arr, k, last, i - 1)
                last = i
            }
        }
        return result
    }

    private fun getCount(arr: CharArray, k: Int, start: Int, end: Int): Int {
        var result = 0
        var i = 1
        while (i <= 26 && i * k <= end - start + 1) {
            val cnt = IntArray(26)
            var good = 0
            for (j in start..end) {
                val cR = arr[j]
                cnt[cR.code - 'a'.code]++
                if (cnt[cR.code - 'a'.code] == k) {
                    good++
                }
                if (cnt[cR.code - 'a'.code] == k + 1) {
                    good--
                }
                if (j >= start + i * k) {
                    val cL = arr[j - i * k]
                    if (cnt[cL.code - 'a'.code] == k) {
                        good--
                    }
                    if (cnt[cL.code - 'a'.code] == k + 1) {
                        good++
                    }
                    cnt[cL.code - 'a'.code]--
                }
                if (good == i) {
                    result++
                }
            }
            i++
        }
        return result
    }
}