Count number of substrings having at least K distinct characters
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 |
Python3
# Python 3 program for the above approach from collections import defaultdict # Function to count number of substrings # having atleast 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 + = 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) # This code is contributed by ukasp. |
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++; 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> |
4
Time Complexity: O(N)
Auxiliary Space: O(k)
Please Login to comment...