Skip to content
geeksforgeeks
  • Courses
    • DSA to Development
    • Get IBM Certification
    • Newly Launched!
      • Master Django Framework
      • Become AWS Certified
    • For Working Professionals
      • Interview 101: DSA & System Design
      • Data Science Training Program
      • JAVA Backend Development (Live)
      • DevOps Engineering (LIVE)
      • Data Structures & Algorithms in Python
    • For Students
      • Placement Preparation Course
      • Data Science (Live)
      • Data Structure & Algorithm-Self Paced (C++/JAVA)
      • Master Competitive Programming (Live)
      • Full Stack Development with React & Node JS (Live)
    • Full Stack Development
    • Data Science Program
    • All Courses
  • Tutorials
    • Data Structures & Algorithms
    • ML & Data Science
    • Interview Corner
    • Programming Languages
    • Web Development
    • CS Subjects
    • DevOps And Linux
    • School Learning
  • Practice
    • Build your AI Agent
    • GfG 160
    • Problem of the Day
    • Practice Coding Problems
    • GfG SDE Sheet
  • Contests
    • Accenture Hackathon (Ending Soon!)
    • GfG Weekly [Rated Contest]
    • Job-A-Thon Hiring Challenge
    • All Contests and Events
  • DSA
  • Interview Problems on String
  • Practice String
  • MCQs on String
  • Tutorial on String
  • String Operations
  • Sort String
  • Substring & Subsequence
  • Iterate String
  • Reverse String
  • Rotate String
  • String Concatenation
  • Compare Strings
  • KMP Algorithm
  • Boyer-Moore Algorithm
  • Rabin-Karp Algorithm
  • Z Algorithm
  • String Guide for CP
Open In App
Next Article:
Check if number of distinct characters in 2 Strings can be made equal
Next article icon

Number of substrings with equal character frequencies and fixed distance

Last Updated : 23 Mar, 2024
Comments
Improve
Suggest changes
Like Article
Like
Report

Given a string S and an integer K, the task is to count the number of substrings which have each character exactly K times and maximum distance between two same characters <= K.

Examples:

Input: S= " de", K = 2
Output: 3
Explanation: "abab", "ababcc" and "cc" are substrings having each character exactly 2 times and the maximum distance between two same characters <= 2.

Input: S = "xyyxx", K = 2
Output: 4
Explanation: "xyyx", "yy", "yyxx" and "xx" are substrings having each character exactly 2 times and the maximum distance between two same characters <= 2.

Approach: To solve the problem, follow the below idea:

The problem can be solved by considering the substrings of all possible lengths. For a particular length, iterate through all the windows of that length. In every window, check if every character occurred exactly K times and the distance between two same characters <= K. If yes, then increment the answer by 1. After iterating over windows of all possible lengths, print the answer.

Step-by-step algorithm:

  • Iterate through all possible substring lengths from 1 to the maximum length. For each substring length, use a sliding window approach to check if any substring of that length satisfies the conditions of being special.
  • Initialize a window and a character frequency map. The window represents the current substring being considered. The character frequency map stores the frequency of each character within the window.
  • Slide the window and update the character frequency map. Iterate through the characters within the window and update their frequencies in the character frequency map.
  • Check if the current window satisfies the conditions:
    • All character frequencies are equal to k or 0 (using the hasEqualFrequency function).
    • The difference between adjacent characters is at most k (using the hasAdjacentDifferenceAtMostTwo function).
  • If both conditions are met, increment the count of special substrings and Move the window forward by one character.
  • If the window has not reached the end of the word, increment the end index of the window and update the frequency of the new character entering the window in the character frequency map.
  • After iterating through all substring lengths, the algorithm returns the total count of special substrings found in the word.

Below is the implementation of the above approach:

C++
#include <bits/stdc++.h> using namespace std;  // Function to check if all character frequencies are equal // to k or 0 bool hasEqualFrequency(unordered_map<char, int>& charFreq,                     int k) {     for (auto& entry : charFreq) {         if (entry.second != k && entry.second != 0) {             return false;         }     }     return true; }  // Function to check if adjacent character difference is at // most two bool hasAdjacentDifferenceAtMostTwo(string& word, int start,                                     int end, int k) {     for (int i = start + 1; i <= end; ++i) {         if (abs(word[i] - word[i - 1]) > k) {             return false;         }     }     return true; }  int countSubstrings(string word, int k) {     int count = 0;     // Count unique characters in the word     int uniqueChars         = unordered_set<char>(word.begin(), word.end())             .size();      // Loop through substring lengths from 1 to the count of     // unique characters     for (int subLen = 1; subLen <= uniqueChars; ++subLen) {         // Define the window size         int windowSize = subLen * k;          // Map to store character frequencies         unordered_map<char, int> charFreq;         int start = 0;         int end = start + windowSize - 1;          // Populate the character frequency map for the         // initial window         for (int i = start;             i <= min(end,                     static_cast<int>(word.length()) - 1);             ++i) {             charFreq[word[i]]++;         }          // Sliding window approach         while (end < word.length()) {             // Check conditions for equal frequency and             // adjacent difference at most two             if (hasEqualFrequency(charFreq, k)                 && hasAdjacentDifferenceAtMostTwo(                     word, start, end, k)) {                 count++;             }              // Move the window by decrementing the start             // character frequency             charFreq[word[start]]--;             start++;             end++;              // Update the end character frequency if the             // window size is less than word length             if (windowSize < word.length()) {                 charFreq[word[end]]++;             }         }     }      return count; }  int main() {      string word = "ababccde";     int k = 2;      int result = countSubstrings(word, k);      cout << result << endl;      return 0; } 
Java
import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import java.util.stream.Collectors;  public class SubstringCount {      // Function to check if all character frequencies are     // equal to k or 0     private static boolean     hasEqualFrequency(Map<Character, Integer> charFreq,                       int k)     {         for (Map.Entry<Character, Integer> entry :              charFreq.entrySet()) {             if (entry.getValue() != k                 && entry.getValue() != 0) {                 return false;             }         }         return true;     }      // Function to check if adjacent character difference is     // at most two     private static boolean     hasAdjacentDifferenceAtMostTwo(String word, int start,                                    int end, int k)     {         for (int i = start + 1; i <= end; ++i) {             if (Math.abs(word.charAt(i)                          - word.charAt(i - 1))                 > k) {                 return false;             }         }         return true;     }      private static int countSubstrings(String word, int k)     {         int count = 0;          // Count unique characters in the word         List<Character> uniqueCharsList             = word.chars()                   .mapToObj(c -> (char)c)                   .collect(Collectors.toList());         int uniqueChars             = new HashSet<>(uniqueCharsList).size();          // Loop through substring lengths from 1 to the         // count of unique characters         for (int subLen = 1; subLen <= uniqueChars;              ++subLen) {             // Define the window size             int windowSize = subLen * k;              // Map to store character frequencies             Map<Character, Integer> charFreq                 = new HashMap<>();             int start = 0;             int end = start + windowSize - 1;              // Populate the character frequency map for the             // initial window             for (int i = start;                  i <= Math.min(end, word.length() - 1);                  ++i) {                 charFreq.put(                     word.charAt(i),                     charFreq.getOrDefault(word.charAt(i), 0)                         + 1);             }              // Sliding window approach             while (end < word.length()) {                 // Check conditions for equal frequency and                 // adjacent difference at most two                 if (hasEqualFrequency(charFreq, k)                     && hasAdjacentDifferenceAtMostTwo(                         word, start, end, k)) {                     count++;                 }                  // Move the window by decrementing the start                 // character frequency                 charFreq.put(                     word.charAt(start),                     charFreq.get(word.charAt(start)) - 1);                 start++;                 end++;                  // Update the end character frequency if the                 // window size is less than or equal to word                 // length                 if (end < word.length()) {                     charFreq.put(word.charAt(end),                                  charFreq.getOrDefault(                                      word.charAt(end), 0)                                      + 1);                 }             }         }          return count;     }      public static void main(String[] args)     {         String word = "ababccde";         int k = 2;          int result = countSubstrings(word, k);          System.out.println(result);     } } // This code is contributed by akshitaguprzj3 
C#
using System; using System.Collections.Generic;  class Program {     // Function to check if all character frequencies are equal to k or 0     static bool HasEqualFrequency(Dictionary<char, int> charFreq, int k)     {         foreach (var value in charFreq.Values)         {             if (value != k && value != 0)             {                 return false;             }         }         return true;     }      // Function to check if adjacent character difference is at most two     static bool HasAdjacentDifferenceAtMostTwo(string word, int start, int end, int k)     {         for (int i = start + 1; i <= end; ++i)         {             if (Math.Abs(word[i] - word[i - 1]) > k)             {                 return false;             }         }         return true;     }      static int CountSubstrings(string word, int k)     {         int count = 0;          // Count unique characters in the word         int uniqueChars = new HashSet<char>(word).Count;          // Loop through substring lengths from 1 to the count of unique characters         for (int subLen = 1; subLen <= uniqueChars; ++subLen)         {             // Define the window size             int windowSize = subLen * k;              // Dictionary to store character frequencies             Dictionary<char, int> charFreq = new Dictionary<char, int>();             int start = 0;             int end = start + windowSize - 1;              // Populate the character frequency map for the initial window             for (int i = start; i <= Math.Min(end, word.Length - 1); ++i)             {                 charFreq[word[i]] = charFreq.ContainsKey(word[i]) ? charFreq[word[i]] + 1 : 1;             }              // Sliding window approach             while (end < word.Length)             {                 // Check conditions for equal frequency and adjacent difference at most two                 if (HasEqualFrequency(charFreq, k) && HasAdjacentDifferenceAtMostTwo(word, start, end, k))                 {                     count++;                 }                  // Move the window by decrementing the start character frequency                 charFreq[word[start]]--;                 start++;                 end++;                  // Update the end character frequency if the window size is less than or equal to word length                 if (end < word.Length)                 {                     charFreq[word[end]] = charFreq.ContainsKey(word[end]) ? charFreq[word[end]] + 1 : 1;                 }             }         }          return count;     }      static void Main(string[] args)     {         string word = "ababccde";         int k = 2;          int result = CountSubstrings(word, k);          Console.WriteLine(result);     } } 
JavaScript
// Function to check if all character frequencies are equal // to k or 0 function hasEqualFrequency(charFreq, k) {     for (const entry of Object.entries(charFreq)) {         if (entry[1] !== k && entry[1] !== 0) {             return false;         }     }     return true; }  // Function to check if adjacent character difference is at // most two function hasAdjacentDifferenceAtMostTwo(word, start, end, k) {     for (let i = start + 1; i <= end; ++i) {         if (Math.abs(word[i].charCodeAt(0) - word[i - 1].charCodeAt(0)) > k) {             return false;         }     }     return true; }  function countSubstrings(word, k) {     let count = 0;      // Count unique characters in the word     const uniqueChars = new Set(word).size;      // Loop through substring lengths from 1 to the count of     // unique characters     for (let subLen = 1; subLen <= uniqueChars; ++subLen) {         // Define the window size         const windowSize = subLen * k;          // Map to store character frequencies         const charFreq = {};          let start = 0;         let end = start + windowSize - 1;          // Populate the character frequency map for the         // initial window         for (let i = start; i <= Math.min(end, word.length - 1); ++i) {             charFreq[word[i]] = (charFreq[word[i]] || 0) + 1;         }          // Sliding window approach         while (end < word.length) {             // Check conditions for equal frequency and             // adjacent difference at most two             if (hasEqualFrequency(charFreq, k) && hasAdjacentDifferenceAtMostTwo(word, start, end, k)) {                 count++;             }              // Move the window by decrementing the start             // character frequency             charFreq[word[start]]--;              start++;             end++;              // Update the end character frequency if the             // window size is less than word length             if (windowSize < word.length) {                 charFreq[word[end]] = (charFreq[word[end]] || 0) + 1;             }         }     }      return count; }  // Example const word = "ababccde"; const k = 2;  const result = countSubstrings(word, k);  console.log(result); 
Python3
def has_equal_frequency(char_freq, k):     # Check if all character frequencies are equal to k or 0     for value in char_freq.values():         if value != k and value != 0:             return False     return True  def has_adjacent_difference_at_most_two(word, start, end, k):     # Check if adjacent character difference is at most two     for i in range(start + 1, end + 1):         if abs(ord(word[i]) - ord(word[i - 1])) > k:             return False     return True  def count_substrings(word, k):     count = 0      # Count unique characters in the word     unique_chars = len(set(word))      # Loop through substring lengths from 1 to the count of unique characters     for sub_len in range(1, unique_chars + 1):         # Define the window size         window_size = sub_len * k          # Dictionary to store character frequencies         char_freq = {}         start = 0         end = start + window_size - 1          # Populate the character frequency map for the initial window         for i in range(start, min(end, len(word) - 1) + 1):             char_freq[word[i]] = char_freq.get(word[i], 0) + 1          # Sliding window approach         while end < len(word):             # Check conditions for equal frequency and adjacent difference at most two             if has_equal_frequency(char_freq, k) and has_adjacent_difference_at_most_two(word, start, end, k):                 count += 1              # Move the window by decrementing the start character frequency             char_freq[word[start]] -= 1             start += 1             end += 1              # Update the end character frequency if the window size is less than or equal to word length             if end < len(word):                 char_freq[word[end]] = char_freq.get(word[end], 0) + 1      return count  def main():     word = "ababccde"     k = 2      result = count_substrings(word, k)      print(result)  if __name__ == "__main__":     main() 

Output
3

Time Complexity: O(N), where N is the length of the string S.
Auxiliary Space: O(1)


Next Article
Check if number of distinct characters in 2 Strings can be made equal
author
akashjha2671
Improve
Article Tags :
  • Strings
  • DSA
Practice Tags :
  • Strings

Similar Reads

  • Count Substrings with even frequency of each character and one exception
    Given a string S ('a' ? S[i] ? 't') of length N (1 ? N ? 105), which consists of lowercase English alphabets, the task is to count all substrings such that the frequency of all characters should be even or all characters should occur an even number of times except any one character which might occur
    6 min read
  • Number of substrings with count of each character as k
    Given a string and an integer k, find the number of substrings in which all the different characters occur exactly k times. Examples: Input : s = "aabbcc" k = 2 Output : 6 The substrings are aa, bb, cc, aabb, bbcc and aabbcc. Input : s = "aabccc" k = 2 Output : 3 There are three substrings aa, cc an
    15 min read
  • Check equal frequency of distinct characters in string with 1 or 0 removals
    Given a string S having lowercase alphabets, the task is to check if all distinct characters in S occurs same number of times by removing 1 or 0 characters from it. Examples : Input : string str = "abbca"Output : YesExplanation: We can make it valid by removing "c" Input : string str = "aabbcd"Outpu
    15+ min read
  • Check if number of distinct characters in 2 Strings can be made equal
    Given two strings A and B of lowercase English letters of lengths N and M respectively. Check whether the number of distinct characters in both strings A and B can be made equal by applying the operation at most one time. Where operation is: Choose any index i such that 0 ≤ i ≤ N from string A and i
    15 min read
  • Find minimum number of Substrings with unique characters
    Given string 's', the task is to divide a given string s into multiple substrings, with each substring containing only unique characters. This means that no character should be repeated within a single substring. The goal is to find the minimum number of such substrings required to satisfy this cond
    12 min read
  • 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 = 3Output: 4Explanation:The substrings that contain at least K(= 3) distinct characters are: "abc": Count of dist
    7 min read
  • Queries for frequencies of characters in substrings
    Given a string s and Q number of queries. Each query Q consists of l and r and a character c. Find the frequency of character c in substring l to r. Examples: Input : s = geeksforgeeks 4 0 5 e 2 6 f 4 7 m 0 12 e Output : 2 1 0 4 Substring from 0 to 5 is geeksf. Here e occurs 2 times. Input : s = app
    6 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 of substrings of given string with frequency of each character at most K
    Given a string str, the task is to calculate the number of substrings of the given string such that the frequency of each element of the string is almost K. Examples: Input: str = "abab", K = 1Output: 7Explanation: The substrings such that the frequency of each character is atmost 1 are "a", "b", "a
    6 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
geeksforgeeks-footer-logo
Corporate & Communications Address:
A-143, 7th Floor, Sovereign Corporate Tower, Sector- 136, Noida, Uttar Pradesh (201305)
Registered Address:
K 061, Tower K, Gulshan Vivante Apartment, Sector 137, Noida, Gautam Buddh Nagar, Uttar Pradesh, 201305
GFG App on Play Store GFG App on App Store
Advertise with us
  • Company
  • About Us
  • Legal
  • Privacy Policy
  • In Media
  • Contact Us
  • Advertise with us
  • GFG Corporate Solution
  • Placement Training Program
  • Languages
  • Python
  • Java
  • C++
  • PHP
  • GoLang
  • SQL
  • R Language
  • Android Tutorial
  • Tutorials Archive
  • DSA
  • Data Structures
  • Algorithms
  • DSA for Beginners
  • Basic DSA Problems
  • DSA Roadmap
  • Top 100 DSA Interview Problems
  • DSA Roadmap by Sandeep Jain
  • All Cheat Sheets
  • Data Science & ML
  • Data Science With Python
  • Data Science For Beginner
  • Machine Learning
  • ML Maths
  • Data Visualisation
  • Pandas
  • NumPy
  • NLP
  • Deep Learning
  • Web Technologies
  • HTML
  • CSS
  • JavaScript
  • TypeScript
  • ReactJS
  • NextJS
  • Bootstrap
  • Web Design
  • Python Tutorial
  • Python Programming Examples
  • Python Projects
  • Python Tkinter
  • Python Web Scraping
  • OpenCV Tutorial
  • Python Interview Question
  • Django
  • Computer Science
  • Operating Systems
  • Computer Network
  • Database Management System
  • Software Engineering
  • Digital Logic Design
  • Engineering Maths
  • Software Development
  • Software Testing
  • DevOps
  • Git
  • Linux
  • AWS
  • Docker
  • Kubernetes
  • Azure
  • GCP
  • DevOps Roadmap
  • System Design
  • High Level Design
  • Low Level Design
  • UML Diagrams
  • Interview Guide
  • Design Patterns
  • OOAD
  • System Design Bootcamp
  • Interview Questions
  • Inteview Preparation
  • Competitive Programming
  • Top DS or Algo for CP
  • Company-Wise Recruitment Process
  • Company-Wise Preparation
  • Aptitude Preparation
  • Puzzles
  • School Subjects
  • Mathematics
  • Physics
  • Chemistry
  • Biology
  • Social Science
  • English Grammar
  • Commerce
  • World GK
  • GeeksforGeeks Videos
  • DSA
  • Python
  • Java
  • C++
  • Web Development
  • Data Science
  • CS Subjects
@GeeksforGeeks, Sanchhaya Education Private Limited, All rights reserved
We use cookies to ensure you have the best browsing experience on our website. By using our site, you acknowledge that you have read and understood our Cookie Policy & Privacy Policy
Lightbox
Improvement
Suggest Changes
Help us improve. Share your suggestions to enhance the article. Contribute your expertise and make a difference in the GeeksforGeeks portal.
geeksforgeeks-suggest-icon
Create Improvement
Enhance the article with your expertise. Contribute to the GeeksforGeeks community and help create better learning resources for all.
geeksforgeeks-improvement-icon
Suggest Changes
min 4 words, max Words Limit:1000

Thank You!

Your suggestions are valuable to us.

What kind of Experience do you want to share?

Interview Experiences
Admission Experiences
Career Journeys
Work Experiences
Campus Experiences
Competitive Exam Experiences