Count number of substrings having at least K distinct characters
Last Updated :
28 Dec, 2022
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++
#include <bits/stdc++.h>
using namespace std;
void atleastkDistinctChars(string s, int k)
{
int n = s.size();
unordered_map< char , int > mp;
int begin = 0, end = 0;
int ans = 0;
while (end < n) {
char ch = s[end];
mp[ch]++;
end++;
while (mp.size() >= k) {
char pre = s[begin];
mp[pre]--;
if (mp[pre] == 0) {
mp.erase(pre);
}
ans += s.length() - end + 1;
begin++;
}
}
cout << ans;
}
int main()
{
string S = "abcca" ;
int K = 3;
atleastkDistinctChars(S, K);
return 0;
}
|
Java
import java.util.*;
class GFG
{
static void atleastkDistinctChars(String s, int k)
{
int n = s.length();
Map<Character, Integer> mp = new HashMap<>();
int begin = 0 , end = 0 ;
int ans = 0 ;
while (end < n) {
char c = s.charAt(end);
mp.put(c,mp.getOrDefault(c, 0 )+ 1 );
end++;
while (mp.size() >= k) {
char pre = s.charAt(begin);
mp.put(pre,mp.getOrDefault(pre, 0 )- 1 );
if (mp.get(pre)== 0 ){
mp.remove(pre);
}
ans += s.length() - end + 1 ;
begin++;
}
}
System.out.println(ans);
}
public static void main (String[] args)
{
String S = "abcca" ;
int K = 3 ;
atleastkDistinctChars(S, K);
}
}
|
Python3
from collections import defaultdict
def atleastkDistinctChars(s, k):
n = len (s)
mp = defaultdict( int )
begin = 0
end = 0
ans = 0
while (end < n):
c = s[end]
mp + = 1
end + = 1
while ( len (mp) > = k):
pre = s[begin]
mp[pre] - = 1
if (mp[pre] = = 0 ):
del mp[pre]
ans + = len (s) - end + 1
begin + = 1
print (ans)
if __name__ = = "__main__" :
S = "abcca"
K = 3
atleastkDistinctChars(S, K)
|
C#
using System;
using System.Collections.Generic;
class GFG{
static void atleastkDistinctChars( string s, int k)
{
int n = s.Length;
Dictionary< char ,
int > mp = new Dictionary< char ,
int >();
int begin = 0, end = 0;
int ans = 0;
while (end < n)
{
char c = s[end];
if (mp.ContainsKey(c))
mp++;
else
mp.Add(c, 1);
end++;
while (mp.Count >= k)
{
char pre = s[begin];
mp[pre]--;
if (mp[pre] == 0)
{
mp.Remove(pre);
}
ans += s.Length - end + 1;
begin++;
}
}
Console.Write(ans);
}
public static void Main()
{
string S = "abcca" ;
int K = 3;
atleastkDistinctChars(S, K);
}
}
|
Javascript
<script>
function atleastkDistinctChars(s,k)
{
let n = s.length;
let mp = new Map();
let begin = 0, end = 0;
let ans = 0;
while (end < n)
{
let c = s[end];
if (mp.has(c))
mp.set(c,mp.get(c)+1);
else
mp.set(c, 1);
end++;
while (mp.size >= k)
{
let pre = s[begin];
mp.set(pre,mp.get(pre)-1);
if (mp.get(pre) == 0)
{
mp. delete (pre);
}
ans += s.length - end + 1;
begin++;
}
}
document.write(ans);
}
let S = "abcca" ;
let K = 3;
atleastkDistinctChars(S, K);
</script>
|
Time Complexity: O(N)
Auxiliary Space: O(k)
Share your thoughts in the comments
Please Login to comment...