Count substrings with k distinct characters
Last Updated :
24 May, 2025
Given a string s consisting of lowercase characters and an integer k, the task is to count all possible substrings (not necessarily distinct) that have exactly k distinct characters.
Examples:
Input: s = "abc", k = 2
Output: 2
Explanation: Possible substrings are ["ab", "bc"]
Input: s = "aba", k = 2
Output: 3
Explanation: Possible substrings are ["ab", "ba", "aba"]
Input: s = "aa", k = 1
Output: 3
Explanation: Possible substrings are ["a", "a", "aa"]
[Naive Approach] Checking all Substrings - O(n^2) time and O(1) space
The idea is to check every possible substring by iterating through all possible starting positions (i) and ending positions (j) in the string. For each substring, maintain a boolean array to track distinct characters and a counter for the number of distinct characters. As it expands the substring from left to right, it updates the distinct character count by checking if each new character has been seen before. Whenever the number of distinct characters exactly matches the given k, it increments the answer count.
C++
// C++ program to find substrings
// with K Distinct characters
#include <bits/stdc++.h>
using namespace std;
int countSubstr(string &s, int k) {
int n = s.length();
int ans = 0;
for (int i=0; i<n; i++) {
// Array to check if a character
// is present in substring i..j
vector<bool> map(26, 0);
int distinctCnt = 0;
for (int j=i; j<n; j++) {
// If new character is present,
// increment distinct count.
if (map[s[j] - 'a'] == false) {
map[s[j] - 'a'] = true;
distinctCnt++;
}
// If distinct count is equal to k.
if (distinctCnt == k) ans++;
}
}
return ans;
}
int main() {
string s = "abc";
int k = 2;
cout << countSubstr(s, k);
return 0;
}
Java
// Java program to find substrings
// with K Distinct characters
import java.util.*;
class GfG {
static int countSubstr(String s, int k) {
int n = s.length();
int ans = 0;
for (int i = 0; i < n; i++) {
// Array to check if a character
// is present in substring i..j
boolean[] map = new boolean[26];
int distinctCnt = 0;
for (int j = i; j < n; j++) {
// If new character is present,
// increment distinct count.
if (!map[s.charAt(j) - 'a']) {
map[s.charAt(j) - 'a'] = true;
distinctCnt++;
}
// If distinct count is equal to k.
if (distinctCnt == k) ans++;
}
}
return ans;
}
public static void main(String[] args) {
String s = "abc";
int k = 2;
System.out.println(countSubstr(s, k));
}
}
Python
# Python program to find substrings
# with K Distinct characters
def countSubstr(s, k):
n = len(s)
ans = 0
for i in range(n):
# Array to check if a character
# is present in substring i..j
map = [False] * 26
distinctCnt = 0
for j in range(i, n):
# If new character is present,
# increment distinct count.
if not map[ord(s[j]) - ord('a')]:
map[ord(s[j]) - ord('a')] = True
distinctCnt += 1
# If distinct count is equal to k.
if distinctCnt == k:
ans += 1
return ans
if __name__ == "__main__":
s = "abc"
k = 2
print(countSubstr(s, k))
C#
// C# program to find substrings
// with K Distinct characters
using System;
class GfG {
static int countSubstr(string s, int k) {
int n = s.Length;
int ans = 0;
for (int i = 0; i < n; i++) {
// Array to check if a character
// is present in substring i..j
bool[] map = new bool[26];
int distinctCnt = 0;
for (int j = i; j < n; j++) {
// If new character is present,
// increment distinct count.
if (!map[s[j] - 'a']) {
map[s[j] - 'a'] = true;
distinctCnt++;
}
// If distinct count is equal to k.
if (distinctCnt == k) ans++;
}
}
return ans;
}
static void Main() {
string s = "abc";
int k = 2;
Console.WriteLine(countSubstr(s, k));
}
}
JavaScript
// JavaScript program to find substrings
// with K Distinct characters
function countSubstr(s, k) {
let n = s.length;
let ans = 0;
for (let i = 0; i < n; i++) {
// Array to check if a character
// is present in substring i..j
let map = new Array(26).fill(false);
let distinctCnt = 0;
for (let j = i; j < n; j++) {
// If new character is present,
// increment distinct count.
if (!map[s.charCodeAt(j) - 'a'.charCodeAt(0)]) {
map[s.charCodeAt(j) - 'a'.charCodeAt(0)] = true;
distinctCnt++;
}
// If distinct count is equal to k.
if (distinctCnt === k) ans++;
}
}
return ans;
}
let s = "abc";
let k = 2;
console.log(countSubstr(s, k));
[Efficient Approach] Using Sliding Window Method - O(n) time and O(1) space
The idea is to use sliding window technique to efficiently count substrings with at most k distinct characters, and then subtract the count of substrings with at most k-1 distinct characters to obtain the number of substrings with exactly k distinct characters.
Step by step approach:
- Use a sliding window with an array of size 26 to track character frequencies.
- Expand the window to the right, adding characters.
- Shrink the window from the left when distinct characters exceed k.
- Count all valid substrings within the window.
- Subtract substrings with k-1 distinct characters from k distinct characters.
C++
// C++ program to find substrings
// with K Distinct characters
#include <bits/stdc++.h>
using namespace std;
// Function which finds the number of
// substrings with atmost k Distinct
// characters.
int count(string &s, int k) {
int n = s.length();
int ans = 0;
// Use sliding window technique
vector<int> freq(26, 0);
int distinctCnt = 0;
int i = 0;
for (int j = 0; j < n; j++) {
// Expand window and add character
freq[s[j] - 'a']++;
if (freq[s[j] - 'a'] == 1) distinctCnt++;
// Shrink window if distinct characters exceed k
while (distinctCnt > k) {
freq[s[i] - 'a']--;
if (freq[s[i] - 'a'] == 0) distinctCnt--;
i++;
}
// Add number of valid substrings ending at j
ans += j - i + 1;
}
return ans;
}
// Function to find the number of substrings
// with exactly k Distinct characters.
int countSubstr(string &s, int k) {
int n = s.length();
int ans = 0;
// Subtract substrings with at most
// k-1 distinct characters from substrings
// with at most k distinct characters
ans = count(s, k) - count(s, k-1);
return ans;
}
int main() {
string s = "abc";
int k = 2;
cout << countSubstr(s, k);
return 0;
}
Java
// Java program to find substrings
// with K Distinct characters
import java.util.*;
class GfG {
// Function which finds the number of
// substrings with atmost k Distinct
// characters.
static int count(String s, int k) {
int n = s.length();
int ans = 0;
// Use sliding window technique
int[] freq = new int[26];
int distinctCnt = 0;
int i = 0;
for (int j = 0; j < n; j++) {
// Expand window and add character
freq[s.charAt(j) - 'a']++;
if (freq[s.charAt(j) - 'a'] == 1) distinctCnt++;
// Shrink window if distinct characters exceed k
while (distinctCnt > k) {
freq[s.charAt(i) - 'a']--;
if (freq[s.charAt(i) - 'a'] == 0) distinctCnt--;
i++;
}
// Add number of valid substrings ending at j
ans += j - i + 1;
}
return ans;
}
// Function to find the number of substrings
// with exactly k Distinct characters.
static int countSubstr(String s, int k) {
int n = s.length();
int ans = 0;
// Subtract substrings with at most
// k-1 distinct characters from substrings
// with at most k distinct characters
ans = count(s, k) - count(s, k - 1);
return ans;
}
public static void main(String[] args) {
String s = "abc";
int k = 2;
System.out.println(countSubstr(s, k));
}
}
Python
# Python program to find substrings
# with K Distinct characters
# Function which finds the number of
# substrings with atmost k Distinct
# characters.
def count(s, k):
n = len(s)
ans = 0
# Use sliding window technique
freq = [0] * 26
distinctCnt = 0
i = 0
for j in range(n):
# Expand window and add character
freq[ord(s[j]) - ord('a')] += 1
if freq[ord(s[j]) - ord('a')] == 1:
distinctCnt += 1
# Shrink window if distinct characters exceed k
while distinctCnt > k:
freq[ord(s[i]) - ord('a')] -= 1
if freq[ord(s[i]) - ord('a')] == 0:
distinctCnt -= 1
i += 1
# Add number of valid substrings ending at j
ans += j - i + 1
return ans
# Function to find the number of substrings
# with exactly k Distinct characters.
def countSubstr(s, k):
n = len(s)
ans = 0
# Subtract substrings with at most
# k-1 distinct characters from substrings
# with at most k distinct characters
ans = count(s, k) - count(s, k - 1)
return ans
if __name__ == "__main__":
s = "abc"
k = 2
print(countSubstr(s, k))
C#
// C# program to find substrings
// with K Distinct characters
using System;
class GfG {
// Function which finds the number of
// substrings with atmost k Distinct
// characters.
static int count(string s, int k) {
int n = s.Length;
int ans = 0;
// Use sliding window technique
int[] freq = new int[26];
int distinctCnt = 0;
int i = 0;
for (int j = 0; j < n; j++) {
// Expand window and add character
freq[s[j] - 'a']++;
if (freq[s[j] - 'a'] == 1) distinctCnt++;
// Shrink window if distinct characters exceed k
while (distinctCnt > k) {
freq[s[i] - 'a']--;
if (freq[s[i] - 'a'] == 0) distinctCnt--;
i++;
}
// Add number of valid substrings ending at j
ans += j - i + 1;
}
return ans;
}
// Function to find the number of substrings
// with exactly k Distinct characters.
static int countSubstr(string s, int k) {
int n = s.Length;
int ans = 0;
// Subtract substrings with at most
// k-1 distinct characters from substrings
// with at most k distinct characters
ans = count(s, k) - count(s, k - 1);
return ans;
}
static void Main() {
string s = "abc";
int k = 2;
Console.WriteLine(countSubstr(s, k));
}
}
JavaScript
// JavaScript program to find substrings
// with K Distinct characters
// Function which finds the number of
// substrings with atmost k Distinct
// characters.
function count(s, k) {
let n = s.length;
let ans = 0;
// Use sliding window technique
let freq = new Array(26).fill(0);
let distinctCnt = 0;
let i = 0;
for (let j = 0; j < n; j++) {
// Expand window and add character
freq[s.charCodeAt(j) - 'a'.charCodeAt(0)]++;
if (freq[s.charCodeAt(j) - 'a'.charCodeAt(0)] === 1) distinctCnt++;
// Shrink window if distinct characters exceed k
while (distinctCnt > k) {
freq[s.charCodeAt(i) - 'a'.charCodeAt(0)]--;
if (freq[s.charCodeAt(i) - 'a'.charCodeAt(0)] === 0) distinctCnt--;
i++;
}
// Add number of valid substrings ending at j
ans += j - i + 1;
}
return ans;
}
// Function to find the number of substrings
// with exactly k Distinct characters.
function countSubstr(s, k) {
let n = s.length;
let ans = 0;
// Subtract substrings with at most
// k-1 distinct characters from substrings
// with at most k distinct characters
ans = count(s, k) - count(s, k - 1);
return ans;
}
let s = "abc";
let k = 2;
console.log(countSubstr(s, k));
Similar Reads
Count of substrings having all distinct characters Given a string str consisting of lowercase alphabets, the task is to find the number of possible substrings (not necessarily distinct) that consists of distinct characters only.Examples: Input: Str = "gffg" Output: 6 Explanation: All possible substrings from the given string are, ( "g", "gf", "gff",
7 min read
Count substrings with same first and last characters Given a string s consisting of lowercase characters, the task is to find the count of all substrings that start and end with the same character.Examples : Input : s = "abcab"Output : 7Explanation: The substrings are "a", "abca", "b", "bcab", "c", "a", "b".Input : s = "aba"Output : 4Explanation: The
7 min read
Count substrings with different first and last characters Given a string S, the task is to print the count of substrings from a given string whose first and last characters are different. Examples: Input: S = "abcab"Output: 8Explanation: There are 8 substrings having first and last characters different {ab, abc, abcab, bc, bca, ca, cab, ab}. Input: S = "ab
10 min read
Count of substrings of length K with exactly K-1 distinct characters Given a string s consisting of lowercase characters and an integer k, find the count of all substrings of length k which have exactly k-1 distinct characters.Example:Input: s = "aabab", k = 3 Output: 3Explanation: Substrings of length 3 are "aab", "aba", "bab". All 3 substrings contains 2 distinct c
8 min read
Count substrings made up of a single distinct character Given a string S of length N, the task is to count the number of substrings made up of a single distinct character.Note: For the repetitive occurrences of the same substring, count all repetitions. Examples: Input: str = "geeksforgeeks"Output: 15Explanation: All substrings made up of a single distin
5 min read