problemmediumalgorithmsleetcode-3325leetcode 3325leetcode3325

Count Substrings With K-Frequency Characters I

MediumUpdated: Aug 2, 2025
Practice on:

Problem

Given a string s and an integer k, return the total number of substrings of s where at least one character appears at least k times.

Examples

Example 1


Input: s = "abacb", k = 2

Output: 4

Explanation:

The valid substrings are:

  * `"aba"` (character `'a'` appears 2 times).
  * `"abac"` (character `'a'` appears 2 times).
  * `"abacb"` (character `'a'` appears 2 times).
  * `"bacb"` (character `'b'` appears 2 times).

Example 2


Input: s = "abcde", k = 1

Output: 15

Explanation:

All substrings are valid because every character appears at least once.

Constraints

  • 1 <= s.length <= 3000
  • 1 <= k <= s.length
  • s consists only of lowercase English letters.

Solution

Method 1 – Sliding Window with Frequency Counting

Intuition

For each substring, we want to check if any character appears at least k times. Since the string is not too long (≤ 3000), we can use a sliding window approach: for every possible substring, count the frequency of each character and check if any count reaches k.

Approach

  1. For every possible starting index i, initialize a frequency array of size 26 (for lowercase letters).
  2. For every ending index j ≥ i, increment the count for s[j].
  3. If any character's count reaches k, mark the substring as valid and break (since we only need at least one such character).
  4. Count all such valid substrings.
  5. Return the total count.

Code

C++
class Solution {
public:
    int countSubstrings(string s, int k) {
        int n = s.size(), ans = 0;
        for (int i = 0; i < n; ++i) {
            vector<int> cnt(26, 0);
            for (int j = i; j < n; ++j) {
                cnt[s[j] - 'a']++;
                if (*max_element(cnt.begin(), cnt.end()) >= k) {
                    ans++;
                }
            }
        }
        return ans;
    }
};
Go
type Solution struct{}
func (Solution) CountSubstrings(s string, k int) int {
    n := len(s)
    ans := 0
    for i := 0; i < n; i++ {
        cnt := make([]int, 26)
        for j := i; j < n; j++ {
            cnt[s[j]-'a']++
            for _, v := range cnt {
                if v >= k {
                    ans++
                    break
                }
            }
        }
    }
    return ans
}
Java
class Solution {
    public int countSubstrings(String s, int k) {
        int n = s.length(), ans = 0;
        for (int i = 0; i < n; ++i) {
            int[] cnt = new int[26];
            for (int j = i; j < n; ++j) {
                cnt[s.charAt(j) - 'a']++;
                for (int v : cnt) {
                    if (v >= k) {
                        ans++;
                        break;
                    }
                }
            }
        }
        return ans;
    }
}
Kotlin
class Solution {
    fun countSubstrings(s: String, k: Int): Int {
        val n = s.length
        var ans = 0
        for (i in 0 until n) {
            val cnt = IntArray(26)
            for (j in i until n) {
                cnt[s[j] - 'a']++
                if (cnt.any { it >= k }) {
                    ans++
                }
            }
        }
        return ans
    }
}
Python
class Solution:
    def countSubstrings(self, s: str, k: int) -> int:
        n = len(s)
        ans = 0
        for i in range(n):
            cnt = [0] * 26
            for j in range(i, n):
                cnt[ord(s[j]) - ord('a')] += 1
                if max(cnt) >= k:
                    ans += 1
        return ans
Rust
impl Solution {
    pub fn count_substrings(s: String, k: i32) -> i32 {
        let n = s.len();
        let s = s.as_bytes();
        let mut ans = 0;
        for i in 0..n {
            let mut cnt = vec![0; 26];
            for j in i..n {
                cnt[(s[j] - b'a') as usize] += 1;
                if *cnt.iter().max().unwrap() >= k {
                    ans += 1;
                }
            }
        }
        ans
    }
}
TypeScript
class Solution {
    countSubstrings(s: string, k: number): number {
        const n = s.length;
        let ans = 0;
        for (let i = 0; i < n; ++i) {
            const cnt = Array(26).fill(0);
            for (let j = i; j < n; ++j) {
                cnt[s.charCodeAt(j) - 97]++;
                if (Math.max(...cnt) >= k) {
                    ans++;
                }
            }
        }
        return ans;
    }
}

Complexity

  • ⏰ Time complexity: O(n^2 * 26), where n is the length of s, since we check all substrings and count frequencies.
  • 🧺 Space complexity: O(26) for the frequency array.

Comments