Count of substrings of length K with exactly K distinct characters
Given string str of the lowercase alphabet and an integer K, the task is to count all substrings of length K which have exactly K distinct characters.
Example:
Input: str = “abcc”, K = 2
Output: 2
Explanation:
Possible substrings of length K = 2 are
ab : 2 distinct characters
bc : 2 distinct characters
cc : 1 distinct character
Only two valid substrings exist {“ab”, “bc”}.
Input: str = “aabab”, K = 3
Output: 0
Explanation:
Possible substrings of length K = 3 are
aab : 2 distinct characters
aba : 2 distinct characters
bab : 2 distinct characters
No substrings of length 3 exist with exactly 3 distinct characters.
Naive approach:
The idea is to generate all substrings of length K and, for each substring count, a number of distinct characters. If the length of a string is N, then there can be N – K + 1 substring of length K. Generating these substrings will require O(N) complexity, and checking each substring requires O(K) complexity, hence making the overall complexity like O(N*K).
C++
#include <bits/stdc++.h>
using namespace std;
int countSubstrings(string s, int K)
{
int n = s.size();
int count = 0;
for ( int i = 0; i < n - K + 1; i++) {
string s1 = s.substr(i, K);
unordered_map< char , int > unmap;
for ( auto c : s1)
unmap++;
if (unmap.size() == s1.size())
count++;
}
return count;
}
int main()
{
string str = "aabcdabbcdc" ;
int K = 3;
cout << countSubstrings(str, K) << endl;
return 0;
}
|
Java
import java.util.HashMap;
public class Main {
static int count = 0 ;
static int countSubstrings(String s, int K) {
int n = s.length();
for ( int i = 0 ; i < n - K + 1 ; i++) {
String s1 = s.substring(i, i + K);
HashMap<Character, Integer> unmap = new HashMap<>();
for ( char c : s1.toCharArray()) {
unmap.put(c, unmap.getOrDefault(c, 0 ) + 1 );
}
if (unmap.size() == K) {
count++;
}
}
return count;
}
public static void main(String[] args) {
String str = "aabcdabbcdc" ;
int K = 3 ;
System.out.println(countSubstrings(str, K));
}
}
|
Python3
def countSubstrings(s: str , K: int ) - > int :
n = len (s)
count = 0
for i in range (n - K + 1 ):
s1 = s[i:i + K]
unmap = {}
for c in s1:
if c in unmap:
unmap + = 1
else :
unmap = 1
if len (unmap) = = len (s1):
count + = 1
return count
if __name__ = = "__main__" :
str = "aabcdabbcdc"
K = 3
print (countSubstrings( str , K))
|
C#
using System;
using System.Collections.Generic;
class MainClass {
static int count = 0;
static int CountSubstrings( string s, int K) {
int n = s.Length;
for ( int i = 0; i < n - K + 1; i++) {
string s1 = s.Substring(i, K);
Dictionary< char , int > unmap = new Dictionary< char , int >();
foreach ( char c in s1.ToCharArray()) {
if (unmap.ContainsKey(c)) {
unmap++;
} else {
unmap.Add(c, 1);
}
}
if (unmap.Count == K) {
count++;
}
}
return count;
}
public static void Main( string [] args) {
string str = "aabcdabbcdc" ;
int K = 3;
Console.WriteLine(CountSubstrings(str, K));
}
}
|
Javascript
function countSubstrings(s, K)
{
let n = s.length;
let count = 0;
for (let i = 0; i < n - K + 1; i++) {
let s1 = s.substring(i, i+K);
let unmap = new Map();
for (let c of s1)
{
if (unmap.has(c))
unmap.set(c,unmap.get(c)+1);
else
unmap.set(c, 1);
}
if (unmap.size == s1.length)
count++;
}
return count;
}
let str = "aabcdabbcdc" ;
let K = 3;
document.write(countSubstrings(str, K));
|
Time Complexity: O(N*K)
Auxiliary Space: O(K)
Count of substrings of length K with exactly K distinct characters using Sliding Window Technique:
The idea is to use Window Sliding Technique. Maintain a window of size K and keep a count of all the characters in the window using a HashMap. Traverse through the string reduces the count of the first character of the previous window and adds the frequency of the last character of the current window in the HashMap. If the count of distinct characters in a window of length K is equal to K, increment the answer by 1.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
int countSubstrings(string str, int K)
{
int N = str.size();
int answer = 0;
unordered_map< char , int > map;
for ( int i = 0; i < K; i++) {
map[str[i]]++;
}
if (map.size() == K)
answer++;
for ( int i = K; i < N; i++) {
map[str[i]]++;
map[str[i - K]]--;
if (map[str[i - K]] == 0) {
map.erase(str[i - K]);
}
if (map.size() == K) {
answer++;
}
}
return answer;
}
int main()
{
string str = "aabcdabbcdc" ;
int K = 3;
cout << countSubstrings(str, K) << endl;
return 0;
}
|
Java
import java.util.*;
class GFG{
public static int countSubstrings(String str,
int K)
{
int N = str.length();
int answer = 0 ;
Map<Character,
Integer> map = new HashMap<Character,
Integer>();
for ( int i = 0 ; i < K; i++)
{
if (map.get(str.charAt(i)) == null )
{
map.put(str.charAt(i), 1 );
}
else
{
map.put(str.charAt(i),
map.get(str.charAt(i)) + 1 );
}
}
if (map.size() == K)
answer++;
for ( int i = K; i < N; i++)
{
if (map.get(str.charAt(i)) == null )
{
map.put(str.charAt(i), 1 );
}
else
{
map.put(str.charAt(i),
map.get(str.charAt(i)) + 1 );
}
map.put(str.charAt(i - K),
map.get(str.charAt(i - K)) - 1 );
if (map.get(str.charAt(i - K)) == 0 )
{
map.remove(str.charAt(i - K));
}
if (map.size() == K)
{
answer++;
}
}
return answer;
}
public static void main(String[] args)
{
String str = "aabcdabbcdc" ;
int K = 3 ;
System.out.println(countSubstrings(str, K));
}
}
|
Python3
def countSubstrings( str , K):
N = len ( str )
answer = 0
map = {}
for i in range (K):
map [ str [i]] = map .get( str [i], 0 ) + 1
if ( len ( map ) = = K):
answer + = 1
for i in range (K, N):
map [ str [i]] = map .get( str [i], 0 ) + 1
map [ str [i - K]] - = 1
if ( map [ str [i - K]] = = 0 ):
del map [ str [i - K]]
if ( len ( map ) = = K):
answer + = 1
return answer
if __name__ = = '__main__' :
str = "aabcdabbcdc"
K = 3
print (countSubstrings( str , K))
|
C#
using System;
using System.Collections.Generic;
class GFG{
public static int countSubstrings( string str,
int K)
{
int N = str.Length;
int answer = 0;
Dictionary< char ,
int > map = new Dictionary< char ,
int >();
for ( int i = 0; i < K; i++)
{
if (!map.ContainsKey(str[i]))
{
map[str[i]] = 1;
}
else
{
map[str[i]]++;
}
}
if (map.Count == K)
answer++;
for ( int i = K; i < N; i++)
{
if (!map.ContainsKey(str[i]))
{
map[str[i]] = 1;
}
else
{
map[str[i]]++;
}
map[str[i - K]]--;
if (map[str[i - K]] == 0)
{
map.Remove(str[i - K]);
}
if (map.Count == K)
{
answer++;
}
}
return answer;
}
public static void Main( string [] args)
{
string str = "aabcdabbcdc" ;
int K = 3;
Console.Write(countSubstrings(str, K));
}
}
|
Javascript
<script>
function countSubstrings(str, K)
{
var N = str.length;
var answer = 0;
var map = new Map();
for ( var i = 0; i < K; i++) {
if (map.has(str[i]))
map.set(str[i], map.get(str[i])+1)
else
map.set(str[i], 1)
}
if (map.size == K)
answer++;
for ( var i = K; i < N; i++) {
if (map.has(str[i]))
map.set(str[i], map.get(str[i])+1)
else
map.set(str[i], 1)
if (map.has(str[i-K]))
map.set(str[i-K], map.get(str[i-K])-1)
if (map.has(str[i - K]) && map.get(str[i-K])==0) {
map. delete (str[i - K]);
}
if (map.size == K) {
answer++;
}
}
return answer;
}
var str = "aabcdabbcdc" ;
var K = 3;
document.write( countSubstrings(str, K) );
</script>
|
Time Complexity: O(N)
Auxiliary Space: O(K)
Last Updated :
03 Oct, 2023
Like Article
Save Article
Share your thoughts in the comments
Please Login to comment...