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:
- Store the frequency of each characters of the given string in a frequency array of size 26.
- Initialize two variables start with 0 and end which is the length of the string str.
- Iterate over the string from start to end and count the number of times each character repeats and store it in an array.
- 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.
- 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 returned by the above recursive call.
- If all the characters between start and end is repeated at least K times, then the answer is end – start.
Below is the implementation of the above approach:
// 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;
} |
// 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 |
# 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
# character 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 |
// 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 |
<script> // JavaScript program for the above approach // Function to find the longest subString function longestSubString(start, end, s, k)
{ var left, right;
// Array for counting the number of
// times each character repeats
// count the number of times each
// character repeats from start to end
var count = new Array(26);
// Store the frequency from s[start...end]
for ( var i = start; i < end; i++)
{
count[s.charAt(i) - 'a' ] += 1;
}
// Iterate from [start, end]
for ( var 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 // Given String str var str = "aabbba" ;
var k = 3;
// Function Call document.write(longestSubString(0, str.length, str, k) + "\n" );
// this code is contributed by shivanisinghss2110 </script> |
6
Time Complexity: O(N*log2N)
Auxiliary Space: O(26) ? O(1), no extra space is required, so it is a constant.