Longest sub-string having frequency of each character less than equal to k

Given a string str of length n. The problem is to find the length of the longest sub-string in str having frequency of each character less than equal to the given value k.

Examples :

Input : str = "babcaag", k = 1
Output : 3
abc and bca are the two longest
sub-strings having frequency of each character 
in them less than equal to '1'.

Input : str = "geeksforgeeks", k = 2
Output : 10

Approach: Create an array freq[] of size 26 implemented as hash table to store the frequency of each character of str. Initialize all of its indexes with value ‘0’. Length of the string is n. Now implement the following algorithm.

longSubstring(str, k)
    Initialize start = 0
    Initialize maxLen = 0
    Declare ch
    
    for i = 0 to n-1
        ch = str[i]
    freq[ch - 'a']++
    if k < freq[ch - 'a'] then
        if maxLen < (i - start) then
            maxLen = i - start
        while (k < freq[ch - 'a'])    
            freq[str[start] - 'a']--
        start++

    if maxLen < (n - start) then
        maxLen = n - start
    
    return maxLen

C++

filter_none

edit
close

play_arrow

link
brightness_4
code

// C++ implementation to find
// the length of the longest 
// substring having frequency
// of each character less 
// than equal to k
#include <bits/stdc++.h>
using namespace std;
  
#define SIZE 26
  
// function to find the length
// of the longest substring 
// having frequency of each 
// character less than equal 
// to k
int longSubstring(string str, int k)
{
    // hash table to store frequency
    // of each table
    int freq[SIZE];
  
    // Initialize
    memset(freq, 0, sizeof(freq));
  
    // 'start' index of the current
    // substring
    int start = 0;
  
    // to store the maximum length
    int maxLen = 0;
    char ch;
  
    int n = str.size();
  
    // traverse the string 'str'
    for (int i = 0; i < n; i++)
    {
        // get the current character
        // as 'ch'
        ch = str[i];
  
        // increase frequency of 
        // 'ch' in 'freq[]'
        freq[ch - 'a']++;
  
        // if frequency of 'ch' becomes
        // more than 'k'
        if (freq[ch - 'a'] > k) 
        {
            // update 'maxLen'
            if (maxLen < (i - start))
                maxLen = i - start;
  
            // decrease frequency of 
            // each character as they 
            // are encountered from 
            // the 'start' index until 
            // frequency of 'ch' is 
            // greater than 'k'
            while (freq[ch - 'a'] > k) 
            {
  
                // decrement frequency 
                // by '1'
                freq[str[start] - 'a']--;
  
                // increment 'start'
                start++;
            }
        }
    }
  
    // update maxLen
    if (maxLen < (n - start))
        maxLen = n - start;
  
    // required length
    return maxLen;
}
  
// Driver program to test above
int main()
{
    string str = "babcaag";
    int k = 1;
  
    cout << "Length = "
        << longSubstring(str, k);
    return 0;
}

chevron_right


Java

filter_none

edit
close

play_arrow

link
brightness_4
code

// Java implementation to find
// the length of the longest 
// substring having frequency
// of each character less 
// than equal to k
import java.util.*;
import java.lang.*;
  
public class GfG{
      
    public final static int SIZE = 26;
      
    // function to find the length
    // of the longest substring 
    // having frequency of each 
    // character less than equal 
    // to k
    public static int longSubstring(String str1, 
                                           int k)
    {
        // hash table to store frequency
        // of each table
        int[] freq = new int [SIZE];
  
        char[] str = str1.toCharArray();
  
        // 'start' index of the current
        // substring
        int start = 0;
  
        // to store the maximum length
        int maxLen = 0;
        char ch;
  
        int n = str1.length();
  
        // traverse the string 'str'
        for (int i = 0; i < n; i++)
        {
            // get the current character
            // as 'ch'
            ch = str[i];
  
            // increase frequency of 
            // 'ch' in 'freq[]'
            freq[ch - 'a']++;
  
            // if frequency of 'ch' 
            // becomes more than 'k'
            if (freq[ch - 'a'] > k) 
            {
                // update 'maxLen'
                if (maxLen < (i - start))
                    maxLen = i - start;
  
                // decrease frequency of 
                // each character as they 
                // are encountered from 
                // the 'start' index until 
                // frequency of 'ch' is 
                // greater than 'k'
                while (freq[ch - 'a'] > k) 
                {
  
                    // decrement frequency
                    // by '1'
                    freq[str[start] - 'a']--;
  
                    // increment 'start'
                    start++;
                }
            }
        }
  
        // update maxLen
        if (maxLen < (n - start))
            maxLen = n - start;
  
        // required length
        return maxLen;
    }
      
    // Driver function 
    public static void main(String argc[])
    {
        String str = "babcaag";
        int k = 1;
          
        System.out.println("Length = " +
        longSubstring(str, k));
    }
}
  
/* This code is contributed by Sagar Shukla */

chevron_right


Python3

filter_none

edit
close

play_arrow

link
brightness_4
code

# Python3 implementation to find
# the length of the longest 
# substring having frequency
# of each character less than 
# equal to k
  
# import library
import numpy as np
  
SIZE = 26
  
# Function to find the length
# of the longest sub having
# frequency of each character
# less than equal to k
def longSub(str, k):
      
    # Hash table to store frequency
    # of each table
    freq = np.zeros(26, dtype = np.int )
  
    # 'start' index of the 
    # current substring
    start = 0
  
    # To store the maximum length
    maxLen = 0
      
    n = len(str)
  
    # Traverse the 'str'
    for i in range(0, n):
          
        # Get the current character
        # as 'ch'
        ch = str[i]
  
        # Increase frequency of 
        # 'ch' in 'freq[]'
        freq[ord(ch) - ord('a') ] += 1
  
        # If frequency of 'ch' 
        # becomes more than 'k'
        if (freq[ord(ch) - ord('a')] > k):
            # update 'maxLen'
            if (maxLen < (i - start)):
                maxLen = i - start
  
            # decrease frequency of 
            # each character as they 
            # are encountered from 
            # the 'start' index until 
            # frequency of 'ch' is 
            # greater than 'k'
            while (freq[ord(ch) - ord('a')] > k):
                  
                # decrement frequency 
                # by '1'
                freq[ord(str[start]) - ord('a')] -= 1
  
                # increment 'start'
                start = start + 1
  
    # Update maxLen
    if (maxLen < (n - start)):
        maxLen = n - start
  
    # required length
    return maxLen;
  
  
# Driver Code
str = "babcaag"
k = 1
  
print ("Length =", longSub(str, k))
   
# This code is contributed by 'saloni1297'

chevron_right


C#

filter_none

edit
close

play_arrow

link
brightness_4
code

// C# implementation to find
// the length of the longest 
// substring having frequency
// of each character less 
// than equal to k
using System;
  
class GfG{
      
    public static int SIZE = 26;
      
    // function to find the length
    // of the longest substring 
    // having frequency of each 
    // character less than equal 
    // to k
    public static int longSubstring(String str1, 
                                          int k)
    {
        // hash table to store
        // frequency of each table
        int []freq = new int [SIZE];
  
        char []str = str1.ToCharArray();
  
        // 'start' index of the
        // current substring
        int start = 0;
  
        // to store the maximum length
        int maxLen = 0;
        char ch;
  
        int n = str1.Length;
  
        // traverse the string 'str'
        for (int i = 0; i < n; i++)
        {
            // get the current character
            // as 'ch'
            ch = str[i];
  
            // increase frequency of 
            // 'ch' in 'freq[]'
            freq[ch - 'a']++;
  
            // if frequency of 'ch' 
            // becomes more than 'k'
            if (freq[ch - 'a'] > k) 
            {
                // update 'maxLen'
                if (maxLen < (i - start))
                    maxLen = i - start;
  
                // decrease frequency of 
                // each character as they 
                // are encountered from 
                // the 'start' index until 
                // frequency of 'ch' is 
                // greater than 'k'
                while (freq[ch - 'a'] > k) 
                {
                    // decrement frequency
                    // by '1'
                    freq[str[start] - 'a']--;
  
                    // increment 'start'
                    start++;
                }
            }
        }
  
        // update maxLen
        if (maxLen < (n - start))
            maxLen = n - start;
  
        // required length
        return maxLen;
    }
      
    // Driver function 
    public static void Main()
    {
        String str = "babcaag";
        int k = 1;
          
        Console.Write("Length = " +
                       longSubstring(str, k));
    }
}
  
// This code is contributed by nitin mittal

chevron_right


PHP

filter_none

edit
close

play_arrow

link
brightness_4
code

<?php
// PHP implementation to find
// the length of the longest 
// sub$having frequency
// of each character less 
// than equal to k
$SIZE = 26;
  
// function to find the length
// of the longest sub$
// having frequency of each 
// character less than equal 
// to k
function longSubstring($str, $k)
{
    global $SIZE;
      
    // hash table to
    // store frequency
    // of each table
    $freq = array();
  
    // Initialize
    for($i = 0; $i < $SIZE; $i++)
        $freq[$i] = 0;     
  
    // 'start' index of 
    // the current substring
    $start = 0;
  
    // to store the 
    // maximum length
    $maxLen = 0;
    $ch = '';
  
    $n = strlen($str);
  
    // traverse the $'str'
    for ($i = 0; $i < $n; $i++)
    {
        // get the current 
        // character as 'ch'
        $ch = $str[$i];
  
        // increase frequency 
        // of 'ch' in 'freq[]'
        $freq[ord($ch) - 
              ord('a')]++;
  
        // if frequency of 
        // 'ch' becomes
        // more than 'k'
        if ($freq[ord($ch) - 
                  ord('a')] > $k
        {
            // update 'maxLen'
            if ($maxLen < ($i - $start))
                $maxLen = $i - $start;
  
            // decrease frequency of 
            // each character as they 
            // are encountered from 
            // the 'start' index until 
            // frequency of 'ch' is 
            // greater than 'k'
            while ($freq[ord($ch) - 
                         ord('a')] > $k
            {
  
                // decrement frequency 
                // by '1'
                $freq[ord($str[$start]) - 
                      ord('a')]--;
  
                // increment 'start'
                $start++;
            }
        }
    }
  
    // update maxLen
    if ($maxLen < ($n - $start))
        $maxLen = $n - $start;
  
    // required length
    return $maxLen;
}
  
// Driver Code
$str = "babcaag";
$k = 1;
  
echo ("Length = " .
       longSubstring($str, $k));
  
// This code is contributed by 
// Manish Shaw(manishshaw1)
?>

chevron_right



Output:

Length = 3

Time Complexity: O(n).
Auxiliary Space: O(1).
Because of the while loop the complexity might seem quadratic but if we look closely the inner while loop will traverse the string single time only.”



My Personal Notes arrow_drop_up

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.



Improved By : nitin mittal, manishshaw1



Article Tags :
Practice Tags :


1


Please write to us at contribute@geeksforgeeks.org to report any issue with the above content.