Count number of substrings having at least K distinct characters
Last Updated :
18 Jul, 2024
Given a string S consisting of N characters and a positive integer K, the task is to count the number of substrings having at least K distinct characters.
Examples:
Input: S = "abcca", K = 3
Output: 4
Explanation:
The substrings that contain at least K(= 3) distinct characters are:
- "abc": Count of distinct characters = 3.
- "abcc": Count of distinct characters = 3.
- "abcca": Count of distinct characters = 3.
- "bcca": Count of distinct characters = 3.
Therefore, the total count of substrings is 4.
Input: S = "abcca", K = 4
Output: 0
Naive Approach: The simplest approach to solve the given problem is to generate all substrings of the given string and count those substrings that have at least K distinct characters in them. After checking for all the substrings, print the total count obtained as the result.
Time Complexity: O(N3)
Auxiliary Space: O(1)
Efficient Approach: The above approach can also be optimized by using the concept of Sliding Window and Hashing. Follow the steps below to solve the problem:
- Initialize a variable, say ans as 0 to store the count of substrings having at least K distinct characters.
- Initialize two pointers, begin and end to store the starting and ending point of the sliding window.
- Initialize a HashMap, say M to store the frequency of characters in the window.
- Iterate until end is less than N, and perform the following steps:
- Include the character at the end of the window, by incrementing the value of S[end] in M by 1.
- Iterate until the size of M becomes less than K, and perform the following steps:
- Remove the characters from the start of the window by decrementing the value of S[begin] in M by 1.
- If its frequency becomes 0, then erase it from the map M.
- Count all the substrings starting from begin till N by incrementing ans by (N - end + 1).
- After completing the above steps, print the value of ans as the result.
Below is the implementation of the above approach:
C++
// C++ program for the above approach
#include <bits/stdc++.h>
using namespace std;
// Function to count number of substrings
// having atleast k distinct characters
void atleastkDistinctChars(string s, int k)
{
// Stores the size of the string
int n = s.size();
// Initialize a HashMap
unordered_map<char, int> mp;
// Stores the start and end
// indices of sliding window
int begin = 0, end = 0;
// Stores the required result
int ans = 0;
// Iterate while the end
// pointer is less than n
while (end < n) {
// Include the character at
// the end of the window
char ch = s[end];
mp[ch]++;
// Increment end pointer by 1
end++;
// Iterate until count of distinct
// characters becomes less than K
while (mp.size() >= k) {
// Remove the character from
// the beginning of window
char pre = s[begin];
mp[pre]--;
// If its frequency is 0,
// remove it from the map
if (mp[pre] == 0) {
mp.erase(pre);
}
// Update the answer
ans += s.length() - end + 1;
begin++;
}
}
// Print the result
cout << ans;
}
// Driver Code
int main()
{
string S = "abcca";
int K = 3;
atleastkDistinctChars(S, K);
return 0;
}
Java
// Java program for the above approach
import java.util.*;
class GFG
{
// Function to count number of substrings
// having atleast k distinct characters
static void atleastkDistinctChars(String s, int k)
{
// Stores the size of the string
int n = s.length();
// Initialize a HashMap
Map<Character, Integer> mp = new HashMap<>();
// Stores the start and end
// indices of sliding window
int begin = 0, end = 0;
// Stores the required result
int ans = 0;
// Iterate while the end
// pointer is less than n
while (end < n) {
// Include the character at
// the end of the window
char c = s.charAt(end);
mp.put(c,mp.getOrDefault(c,0)+1);
// Increment end pointer by 1
end++;
// Iterate until count of distinct
// characters becomes less than K
while (mp.size() >= k) {
// Remove the character from
// the beginning of window
char pre = s.charAt(begin);
mp.put(pre,mp.getOrDefault(pre,0)-1);
// If its frequency is 0,
// remove it from the map
if (mp.get(pre)==0){
mp.remove(pre);
}
// Update the answer
ans += s.length() - end + 1;
begin++;
}
}
// Print the result
System.out.println(ans);
}
// Driver code
public static void main (String[] args)
{
// Given inputs
String S = "abcca";
int K = 3;
atleastkDistinctChars(S, K);
}
}
// This code is contributed by offbeat
Python
from collections import defaultdict
# Function to count number of substrings
# having at least k distinct characters
def atleastkDistinctChars(s, k):
# Stores the size of the string
n = len(s)
# Initialize a HashMap
mp = defaultdict(int)
# Stores the start and end indices of sliding window
begin = 0
end = 0
# Stores the required result
ans = 0
# Iterate while the end pointer is less than n
while end < n:
# Include the character at the end of the window
c = s[end]
mp[c] += 1
# Increment end pointer by 1
end += 1
# Iterate until count of distinct characters becomes less than K
while len(mp) >= k:
# Remove the character from the beginning of window
pre = s[begin]
mp[pre] -= 1
# If its frequency is 0, remove it from the map
if mp[pre] == 0:
del mp[pre]
# Update the answer
ans += len(s) - end + 1
begin += 1
# Print the result
print(ans)
# Driver Code
if __name__ == "__main__":
S = "abcca"
K = 3
atleastkDistinctChars(S, K)
C#
// C# program for the above approach
using System;
using System.Collections.Generic;
class GFG{
// Function to count number of substrings
// having atleast k distinct characters
static void atleastkDistinctChars(string s, int k)
{
// Stores the size of the string
int n = s.Length;
// Initialize a HashMap
Dictionary<char,
int> mp = new Dictionary<char,
int>();
// Stores the start and end
// indices of sliding window
int begin = 0, end = 0;
// Stores the required result
int ans = 0;
// Iterate while the end
// pointer is less than n
while (end < n)
{
// Include the character at
// the end of the window
char c = s[end];
if (mp.ContainsKey(c))
mp[c]++;
else
mp.Add(c, 1);
// Increment end pointer by 1
end++;
// Iterate until count of distinct
// characters becomes less than K
while (mp.Count >= k)
{
// Remove the character from
// the beginning of window
char pre = s[begin];
mp[pre]--;
// If its frequency is 0,
// remove it from the map
if (mp[pre] == 0)
{
mp.Remove(pre);
}
// Update the answer
ans += s.Length - end + 1;
begin++;
}
}
// Print the result
Console.Write(ans);
}
// Driver Code
public static void Main()
{
string S = "abcca";
int K = 3;
atleastkDistinctChars(S, K);
}
}
// This code is contributed by bgangwar59
JavaScript
<script>
// Javascript program for the above approach
// Function to count number of substrings
// having atleast k distinct characters
function atleastkDistinctChars(s,k)
{
// Stores the size of the string
let n = s.length;
// Initialize a HashMap
let mp = new Map();
// Stores the start and end
// indices of sliding window
let begin = 0, end = 0;
// Stores the required result
let ans = 0;
// Iterate while the end
// pointer is less than n
while (end < n)
{
// Include the character at
// the end of the window
let c = s[end];
if (mp.has(c))
mp.set(c,mp.get(c)+1);
else
mp.set(c, 1);
// Increment end pointer by 1
end++;
// Iterate until count of distinct
// characters becomes less than K
while (mp.size >= k)
{
// Remove the character from
// the beginning of window
let pre = s[begin];
mp.set(pre,mp.get(pre)-1);
// If its frequency is 0,
// remove it from the map
if (mp.get(pre) == 0)
{
mp.delete(pre);
}
// Update the answer
ans += s.length - end + 1;
begin++;
}
}
// Print the result
document.write(ans);
}
// Driver Code
let S = "abcca";
let K = 3;
atleastkDistinctChars(S, K);
// This code is contributed by rag2127
</script>
Time Complexity: O(N)
Auxiliary Space: O(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 of Substrings with at least K pairwise Distinct Characters having same Frequency Given a string S and an integer K, the task is to find the number of substrings which consists of at least K pairwise distinct characters having same frequency. Examples: Input: S = "abasa", K = 2 Output: 5 Explanation: The substrings in having 2 pairwise distinct characters with same frequency are
7 min read
Count number of distinct substrings of a given length Given a string S of length N consisting of lower-case English alphabets and an integer 'l', find the number of distinct substrings of length 'l' of the given string. Examples: Input : s = "abcbab", l = 2 Output : 4 All distinct sub-strings of length 2 will be {"ab", "bc", "cb", "ba"} Thus, answer eq
6 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