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 reutnr 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 above approach:
C++
// 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
// 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
# 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
C#
// 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
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. To complete your preparation from learning a language to DS Algo and many more, please refer Complete Interview Preparation Course.