Given a string S containing lowercase latin letters. A character c is called K-amazing if every substring of S with length atleast K contains this character c. Find the minimum possible K such that there exists atleast one K-amazing character.
Examples:
Input : S = “abcde”
Output :3
Explanation : Every substring of length atleast 3 contains character ‘c’, i.e.
{“abc”, “bcd”, “cde”, “abcd”, “bcde”, “abcde”}
Input :S = “aaaa”
Output :1
Prerequisites : Binary Search
Naive Solution : A simple approach is to iterate over all possible lengths of substrings i.e. from 1 to N (size of string) and for every current length substrings check whether some character appears in all of those substrings.
Efficient Solution :
The key idea is to perform binary search over the answer K, since if some character c appears in all substrings of length X, it will always appear in all substrings of length (X + 1). Hence, we can check for the current length and try to minimise it using divide and conquer algorithm. For checking if some character appears in all substrings of length X, iterate over all characters from ‘a’ to ‘z’ and inside another loop iteratively store the last occurrence of the last character.
Let the current position be j, so the last substring of length X will be from (j – X) to X. Check if the position of last occurrence of current K-amazing character is greater than (j – X) or not. If it is greater, then that substring is a valid string.
Below is the implementation of the above approach.
C++
#include <bits/stdc++.h>
using namespace std;
int check(string s, int K)
{
for ( int ch = 0; ch < 26; ch++) {
char c = 'a' + ch;
int last = -1;
bool found = true ;
for ( int i = 0; i < K; i++)
if (s[i] == c)
last = i;
if (last == -1)
continue ;
for ( int i = K; i < s.size(); i++) {
if (s[i] == c)
last = i;
if (last <= (i - K)) {
found = false ;
break ;
}
}
if (found)
return 1;
}
return 0;
}
int binarySearch(string s)
{
int low = 1, high = ( int )s.size();
int ans;
while (low <= high) {
int mid = (high + low) >> 1;
if (check(s, mid)) {
ans = mid;
high = mid - 1;
}
else
low = mid + 1;
}
return ans;
}
int32_t main()
{
string s = "abcde" ;
cout << binarySearch(s) << endl;
s = "aaaa" ;
cout << binarySearch(s) << endl;
return 0;
}
|
Java
class GFG
{
static int check(String s, int K)
{
for ( int ch = 0 ; ch < 26 ; ch++) {
char c = ( char )( 'a' + ch);
int last = - 1 ;
boolean found = true ;
for ( int i = 0 ; i < K; i++)
if (s.charAt(i) == c)
last = i;
if (last == - 1 )
continue ;
for ( int i = K; i < s.length(); i++) {
if (s.charAt(i) == c)
last = i;
if (last <= (i - K)) {
found = false ;
break ;
}
}
if (found)
return 1 ;
}
return 0 ;
}
static int binarySearch(String s)
{
int low = 1 , high = s.length();
int ans= 0 ;
while (low <= high) {
int mid = (high + low) >> 1 ;
if (check(s, mid)== 1 ) {
ans = mid;
high = mid - 1 ;
}
else
low = mid + 1 ;
}
return ans;
}
public static void main(String args[])
{
String s = "abcde" ;
System.out.println(binarySearch(s));
s = "aaaa" ;
System.out.println(binarySearch(s));
}
}
|
Python3
def check(s, K):
for ch in range ( 0 , 26 ):
c = chr ( 97 + ch)
last = - 1
found = True
for i in range ( 0 , K):
if s[i] = = c:
last = i
if last = = - 1 :
continue
for i in range (K, len (s)):
if s[i] = = c:
last = i
if last < = (i - K):
found = False
break
if found:
return 1
return 0
def binarySearch(s):
low, high, ans = 1 , len (s), None
while low < = high:
mid = (high + low) >> 1
if check(s, mid):
ans, high = mid, mid - 1
else :
low = mid + 1
return ans
if __name__ = = "__main__" :
s = "abcde"
print (binarySearch(s))
s = "aaaa"
print (binarySearch(s))
|
C#
using System;
class GFG
{
static int check(String s, int K)
{
for ( int ch = 0; ch < 26; ch++) {
char c = ( char )( 'a' + ch);
int last = -1;
bool found = true ;
for ( int i = 0; i < K; i++)
if (s[i] == c)
last = i;
if (last == -1)
continue ;
for ( int i = K; i < s.Length; i++) {
if (s[i] == c)
last = i;
if (last <= (i - K)) {
found = false ;
break ;
}
}
if (found)
return 1;
}
return 0;
}
static int binarySearch(String s)
{
int low = 1, high = s.Length;
int ans=0;
while (low <= high) {
int mid = (high + low) >> 1;
if (check(s, mid)==1) {
ans = mid;
high = mid - 1;
}
else
low = mid + 1;
}
return ans;
}
public static void Main()
{
String s = "abcde" ;
Console.WriteLine(binarySearch(s));
s = "aaaa" ;
Console.WriteLine(binarySearch(s));
}
}
|
PHP
<?php
function check( $s , $K )
{
for ( $ch = 0; $ch < 26; $ch ++)
{
$c = chr (ord( 'a' ) + $ch ) ;
$last = -1;
$found = true;
for ( $i = 0; $i < $K ; $i ++)
if ( $s [ $i ] == $c )
$last = $i ;
if ( $last == -1)
continue ;
for ( $i = $K ; $i < strlen ( $s ); $i ++)
{
if ( $s [ $i ] == $c )
$last = $i ;
if ( $last <= ( $i - $K ))
{
$found = false;
break ;
}
}
if ( $found )
return 1;
}
return 0;
}
function binarySearch( $s )
{
$low = 1 ;
$high = strlen ( $s ) ;
while ( $low <= $high )
{
$mid = ( $high + $low ) >> 1;
if (check( $s , $mid ))
{
$ans = $mid ;
$high = $mid - 1;
}
else
$low = $mid + 1;
}
return $ans ;
}
$s = "abcde" ;
echo binarySearch( $s ) . "\n" ;
$s = "aaaa" ;
echo binarySearch( $s ) . "\n" ;
?>
|
Javascript
<script>
function check(s, K)
{
for ( var ch = 0; ch < 26; ch++) {
var c = String.fromCharCode( 'a' .charCodeAt(0) + ch);
var last = -1;
var found = true ;
for ( var i = 0; i < K; i++)
if (s[i] == c)
last = i;
if (last == -1)
continue ;
for ( var i = K; i < s.length; i++) {
if (s[i] == c)
last = i;
if (last <= (i - K)) {
found = false ;
break ;
}
}
if (found)
return 1;
}
return 0;
}
function binarySearch(s)
{
var low = 1, high = s.length;
var ans;
while (low <= high) {
var mid = (high + low) >> 1;
if (check(s, mid)) {
ans = mid;
high = mid - 1;
}
else
low = mid + 1;
}
return ans;
}
var s = "abcde" ;
document.write( binarySearch(s) + "<br>" );
s = "aaaa" ;
document.write( binarySearch(s) );
</script>
|
Complexity Analysis:
- Time Complexity: O(N * logN * 26), where N is the size of the given string.
- Auxiliary Space: O(1) because constant space is used.
Feeling lost in the world of random DSA topics, wasting time without progress? It's time for a change! Join our DSA course, where we'll guide you on an exciting journey to master DSA efficiently and on schedule.
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 geeks!
Last Updated :
13 Sep, 2022
Like Article
Save Article