Largest substring where all characters appear at least K times | Set 2

Given a string str and an integer K, the task is to find the length of the longest sub-string S such that every character in S appears at least K times.

Examples:

Input: str = “aabbba”, K = 3
Output: 6
Explanation:
In substring aabbba, each character repeats at least k times and its length is 6.

Input: str = “ababacb”, K = 3
Output: 0
Explanation:
There is no substring where each character repeats at least k times.

Naive Approach: We have discussed the Naive Approach in the previous post.



Approach: In this post, we will discuss the approach using Divide and Conquer technique and Recursion. Below are the steps:

  1. Store the frequency of each characters of the given string in a frequency array of size 26.
  2. Initialize two variables start with 0 and end which is the length of the string str.
  3. Iterate over the string from start to end and count the number of times each character repeats and store it in an array.
  4. If any character repeats less than K times, then Divide the string into two halves. If i is the index of the string where we found that the string[i] repeats less than K times, then we divide the string into two halves from start to i and i + 1 to end.
  5. Recursively call for the two halves in the above steps i.e., from start to i and i + 1 to end separately and repeat the Step 2 and 3 and return the maximum of the two values reutnr by the above recursive call.
  6. If all the characters between start and end is repeated at least K times, then the answer is end – start.
  7. Below is the implementation of above approach:

    C++

    filter_none

    edit
    close

    play_arrow

    link
    brightness_4
    code

    // C++ program for the above approach 
    #include <bits/stdc++.h> 
    using namespace std; 
      
    // Function to find the longest substring 
    int longestSubstring(int start, int end, 
                        string s, int k) 
        int left, right; 
      
        // Array for counting the number of 
        // times each character repeats 
        // count the number of times each 
        // character repeats from start to end 
        int count[26] = { 0 }; 
      
        // Store the frequency from s[start...end] 
        for (int i = start; i < end; i++) { 
            count[s[i] - 'a'] += 1; 
        
      
        // Iterate from [start, end] 
        for (int i = start; i < end; i++) { 
      
            if (count[s[i] - 'a'] < k) { 
      
                // Recursive call for left subpart 
                left = longestSubstring(start, 
                                        i, 
                                        s, 
                                        k); 
      
                // Recursive call for right subpart 
                right = longestSubstring(i + 1, 
                                        end, 
                                        s, 
                                        k); 
      
                // Return maximum of left & right 
                return max(left, right); 
            
        
      
        // If all the characters are repeated 
        // at least k times 
        return end - start; 
      
    // Driver Code 
    int main() 
        // Given String str 
        string str = "aabbba"
        int k = 3; 
      
        // Function Call 
        cout << longestSubstring(0, str.length(), 
                                str, k) 
            << endl; 
        return 0; 

    chevron_right

    
    

    Java

    filter_none

    edit
    close

    play_arrow

    link
    brightness_4
    code

    // Java program for the above approach 
    import java.util.*; 
      
    class GFG{ 
      
    // Function to find the longest subString 
    static int longestSubString(int start, int end, 
                                String s, int k) 
        int left, right; 
      
        // Array for counting the number of 
        // times each character repeats 
        // count the number of times each 
        // character repeats from start to end 
        int count[] = new int[26]; 
      
        // Store the frequency from s[start...end] 
        for(int i = start; i < end; i++) 
        
            count[s.charAt(i) - 'a'] += 1
        
      
        // Iterate from [start, end] 
        for(int i = start; i < end; i++) 
        
            if (count[s.charAt(i) - 'a'] < k) 
            
                  
                // Recursive call for left subpart 
                left = longestSubString(start, i, 
                                        s, k); 
      
                // Recursive call for right subpart 
                right = longestSubString(i + 1, end, 
                                        s, k); 
      
                // Return maximum of left & right 
                return Math.max(left, right); 
            
        
      
        // If all the characters are repeated 
        // at least k times 
        return end - start; 
      
    // Driver Code 
    public static void main(String[] args) 
      
        // Given String str 
        String str = "aabbba"
        int k = 3
      
        // Function Call 
        System.out.print(longestSubString(0, str.length(), 
                                            str, k) + "\n"); 
      
    // This code is contributed by Amit Katiyar 

    chevron_right

    
    

    Python3

    filter_none

    edit
    close

    play_arrow

    link
    brightness_4
    code

    # Python3 program for the above approach 
      
    # Function to find the longest substring 
    def longestSubString(start, end, s, k): 
          
        # List for counting the number of 
        # times each character repeats 
        # count the number of times each 
        # chracter repeats from start to end 
        count = [0 for i in range(26)] 
          
        # Store the frequency from s[start...end] 
        for i in range(start, end): 
            count[ord(s[i]) - ord('a')] += 1
          
        # Iterate from [start, end] 
        for i in range(start, end): 
            if(count[ ord(s[i]) - ord('a')] < k): 
                  
                # Recursive call for left subpart 
                left = longestSubString(start, i, 
                                            s, k) 
                                          
                # Recursive call for right subpart 
                right = longestSubString(i + 1, end, 
                                            s, k) 
                                          
                # Return maximum of left & right 
                return max(left, right) 
          
        # If all the characters are repeated 
        # at least k times 
        return end - start 
          
    # Driver Code 
      
    # Given String str 
    str = "aabbba"
    k = 3
      
    # Function call 
    print(longestSubString(0, len(str), str, k)) 
      
    # This code is contributed by dadimadhav

    chevron_right

    
    

    C#

    filter_none

    edit
    close

    play_arrow

    link
    brightness_4
    code

    // C# program for the above approach
    using System;
      
    class GFG{
      
    // Function to find the longest subString
    static int longestSubString(int start, int end,
                                 string s, int k)
    {
        int left, right;
      
        // Array for counting the number of
        // times each character repeats
        // count the number of times each
        // character repeats from start to end
        int []count = new int[26];
      
        // Store the frequency from s[start...end]
        for(int i = start; i < end; i++)
        {
            count[s[i] - 'a'] += 1;
        }
      
        // Iterate from [start, end]
        for(int i = start; i < end; i++)
        {
            if (count[s[i] - 'a'] < k) 
            {
                  
                // Recursive call for left subpart
                left = longestSubString(start, i,
                                        s, k);
      
                // Recursive call for right subpart
                right = longestSubString(i + 1, end,
                                         s, k);
      
                // Return maximum of left & right
                return Math.Max(left, right);
            }
        }
      
        // If all the characters are repeated
        // at least k times
        return end - start;
    }
      
    // Driver Code
    public static void Main(string[] args)
    {
          
        // Given String str
        string str = "aabbba";
        int k = 3;
      
        // Function call
        Console.Write(longestSubString(0, str.Length,
                                          str, k) + "\n");
    }
    }
      
    // This code is contributed by rutvik_56

    chevron_right

    
    

    Output:

    6
    

    Time Complexity: O(N*log2N)

    Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.




    My Personal Notes arrow_drop_up

    Recommended Posts:


    Check out this Author's contributed articles.

    If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

    Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.