Longest substring where all the characters appear at least K times | Set 3
Last Updated :
03 Jun, 2022
Given a string str and an integer K, the task is to find the length of the longest substring 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: The simplest approach to solve the given problem is discussed in Set 1.
Time Complexity: O(N2)
Auxiliary Space: O(26)
Divide and Conquer Approach: The divide and conquer approach for the given problem is discussed in the Set 2.
Time Complexity: O(N*log N)
Auxiliary Space: O(26)
Efficient Approach: The above two approaches can be optimized further by using Sliding Window technique. Follow the steps below to solve the problem:
- Store the number of unique characters in the string str in a variable, say unique.
- Initialize an array freq[] of size 26 with {0} and store the frequency of each character in this array.
- Iterate over the range [1, unique] using the variable curr_unique. In each iteration, curr_unique is the maximum number of unique characters that must be present in the window.
- Reinitialize the array freq[] with {0} to store the frequency of each character in this window.
- Initialize start and end as 0, to store the starting and the ending point of the window respectively.
- Use two variables cnt, for storing the number of unique characters and countK, for storing the number of characters with at least K repeating characters in the current window.
- Now, iterate a loop while end < N, and perform the following:
- If the value of cnt is less than or equals to curr_unique, then expand the window from the right by adding a character to the end of the window. And increment its frequency by 1 in freq[].
- Otherwise, reduce the window from the left by removing a character from start and decrementing its frequency by 1 in freq[].
- At every step, update the values of cnt and countK.
- If the value of cnt is same as curr_unique and each character occurs at least K times, then update the overall maximum length and store it in ans.
- After completing the above steps, print the value of ans as the result.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
int longestSubstring(string s, int k)
{
int ans = 0;
int freq[26] = { 0 };
int n = s.size();
for ( int i = 0; i < n; i++)
freq[s[i] - 'a' ]++;
int unique = 0;
for ( int i = 0; i < 26; i++)
if (freq[i] != 0)
unique++;
for ( int curr_unique = 1;
curr_unique <= unique;
curr_unique++) {
memset (freq, 0, sizeof (freq));
int start = 0, end = 0;
int cnt = 0, count_k = 0;
while (end < n) {
if (cnt <= curr_unique) {
int ind = s[end] - 'a' ;
if (freq[ind] == 0)
cnt++;
freq[ind]++;
if (freq[ind] == k)
count_k++;
end++;
}
else {
int ind = s[start] - 'a' ;
if (freq[ind] == k)
count_k--;
freq[ind]--;
if (freq[ind] == 0)
cnt--;
start++;
}
if (cnt == curr_unique
&& count_k == curr_unique)
ans = max(ans, end - start);
}
}
return ans;
}
int main()
{
string S = "aabbba" ;
int K = 3;
cout << longestSubstring(S, K) << endl;
return 0;
}
|
Java
import java.util.*;
class GFG
{
static void longestSubString( char [] s, int k)
{
int ans = 0 ;
int freq[] = new int [ 26 ];
int n = s.length;
for ( int i = 0 ; i < n; i++)
freq[s[i] - 'a' ]++;
int unique = 0 ;
for ( int i = 0 ; i < 26 ; i++)
if (freq[i] != 0 )
unique++;
for ( int curr_unique = 1 ;
curr_unique <= unique;
curr_unique++)
{
Arrays.fill(freq, 0 );
int start = 0 , end = 0 ;
int cnt = 0 , count_k = 0 ;
while (end < n)
{
if (cnt <= curr_unique)
{
int ind = s[end] - 'a' ;
if (freq[ind] == 0 )
cnt++;
freq[ind]++;
if (freq[ind] == k)
count_k++;
end++;
}
else
{
int ind = s[start] - 'a' ;
if (freq[ind] == k)
count_k--;
freq[ind]--;
if (freq[ind] == 0 )
cnt--;
start++;
}
if (cnt == curr_unique
&& count_k == curr_unique)
ans = Math.max(ans, end - start);
}
}
System.out.print(ans);
}
public static void main(String[] args)
{
String S = "aabbba" ;
int K = 3 ;
longestSubString(S.toCharArray(), K);
}
}
|
Python3
def longestSubstring(s, k) :
ans = 0
freq = [ 0 ] * 26
n = len (s)
for i in range (n) :
freq[ ord (s[i]) - ord ( 'a' )] + = 1
unique = 0
for i in range ( 26 ) :
if (freq[i] ! = 0 ) :
unique + = 1
for curr_unique in range ( 1 , unique + 1 ) :
Freq = [ 0 ] * 26
start, end = 0 , 0
cnt, count_k = 0 , 0
while (end < n) :
if (cnt < = curr_unique) :
ind = ord (s[end]) - ord ( 'a' )
if (Freq[ind] = = 0 ) :
cnt + = 1
Freq[ind] + = 1
if (Freq[ind] = = k) :
count_k + = 1
end + = 1
else :
ind = ord (s[start]) - ord ( 'a' )
if (Freq[ind] = = k) :
count_k - = 1
Freq[ind] - = 1
if (Freq[ind] = = 0 ) :
cnt - = 1
start + = 1
if ((cnt = = curr_unique) and (count_k = = curr_unique)) :
ans = max (ans, end - start)
print (ans)
S = "aabbba"
K = 3
longestSubstring(S, K)
|
C#
using System;
class GFG
{
static void longestSubstring( string s, int k)
{
int ans = 0;
int [] freq = new int [26];
int n = s.Length;
for ( int i = 0; i < n; i++)
freq[s[i] - 'a' ]++;
int unique = 0;
for ( int i = 0; i < 26; i++)
if (freq[i] != 0)
unique++;
for ( int curr_unique = 1;
curr_unique <= unique;
curr_unique++)
{
for ( int i = 0; i < freq.Length; i++)
{
freq[i] = 0;
}
int start = 0, end = 0;
int cnt = 0, count_k = 0;
while (end < n)
{
if (cnt <= curr_unique)
{
int ind = s[end] - 'a' ;
if (freq[ind] == 0)
cnt++;
freq[ind]++;
if (freq[ind] == k)
count_k++;
end++;
}
else
{
int ind = s[start] - 'a' ;
if (freq[ind] == k)
count_k--;
freq[ind]--;
if (freq[ind] == 0)
cnt--;
start++;
}
if (cnt == curr_unique
&& count_k == curr_unique)
ans = Math.Max(ans, end - start);
}
}
Console.Write(ans);
}
public static void Main()
{
string S = "aabbba" ;
int K = 3;
longestSubstring(S, K);
}
}
|
Javascript
<script>
function longestSubstring(s, k)
{
let ans = 0;
let freq = new Array(26);
freq.fill(0);
let n = s.length;
for (let i = 0; i < n; i++)
freq[s[i].charCodeAt() -
'a' .charCodeAt()]++;
let unique = 0;
for (let i = 0; i < 26; i++)
if (freq[i] != 0)
unique++;
for (let curr_unique = 1;
curr_unique <= unique;
curr_unique++)
{
for (let i = 0; i < freq.length; i++)
{
freq[i] = 0;
}
let start = 0, end = 0;
let cnt = 0, count_k = 0;
while (end < n)
{
if (cnt <= curr_unique)
{
let ind = s[end].charCodeAt() -
'a' .charCodeAt();
if (freq[ind] == 0)
cnt++;
freq[ind]++;
if (freq[ind] == k)
count_k++;
end++;
}
else
{
let ind = s[start].charCodeAt() -
'a' .charCodeAt();
if (freq[ind] == k)
count_k--;
freq[ind]--;
if (freq[ind] == 0)
cnt--;
start++;
}
if (cnt == curr_unique
&& count_k == curr_unique)
ans = Math.max(ans, end - start);
}
}
document.write(ans);
}
let S = "aabbba" ;
let K = 3;
longestSubstring(S, K);
</script>
|
Time Complexity: O(N)
Auxiliary Space: O(1)
Like Article
Suggest improvement
Share your thoughts in the comments
Please Login to comment...