Minimize length of Substrings containing at least one common Character
Last Updated :
05 Sep, 2022
Given a string str, the task is to find the minimum length of substrings such that all the sub strings of that length from str contains at least one common character. If no such length can be obtained, print -1.
Example:
Input: str = “saad”
Output: 2
Explanation:
All the substrings of length two of a given string are {“sa”, “aa”, “ad”}.
Since ‘a’ is common among all the substring, the minimum possible length of substrings having at least one common character is 2.
Input: str = “geeksforgeeks”
Output: 7
Explanation:
All possible substrings of length 7 are as follows:
- geeksfo
- eeksfor
- eksforg
- ksforge
- sforgee
- forgeek
- orgeeks
Since all the substrings have a common character e, the minimum possible length of substrings having at least one common character is 7.
Approach: This problem can be solved easily by using the Binary search Technique. Follow the steps below to solve the problem:
- Initialize low as 1 and high as a length of the string str.
- Find mid between low and high.
- If there is a one common character in all the sub strings of given string, then update high as mid -1.
- If it is not the case, then Update low as a mid + 1.
- Repeat the above steps for all the 26 possible characters in the alphabet.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
bool check(string& str, int mid, char a)
{
int n = str.size();
int previous = -1, i;
for (i = 0; i < n; ++i) {
if (str[i] == a) {
if (i - previous > mid) {
return false ;
}
previous = i;
}
}
if (i - previous > mid)
return false ;
else
return true ;
}
bool possible(string& str, int mid)
{
for ( int i = 0; i < 26; ++i) {
if (check(str, mid, i + 'a' ))
return true ;
}
return false ;
}
int findMinLength(string& str)
{
int low = 1, high = str.length();
while (low <= high) {
int mid = (low + high) / 2;
if (possible(str, mid))
high = mid - 1;
else
low = mid + 1;
}
return high + 1;
}
bool ifAllDistinct(string str)
{
set< char > s;
for ( char c : str) {
s.insert(c);
}
return s.size() == str.size();
}
int main()
{
string str = "geeksforgeeks" ;
if (ifAllDistinct(str))
cout << -1 << endl;
else
cout << findMinLength(str);
return 0;
}
|
Java
import java.util.*;
class GFG{
static boolean check( char [] str, int mid,
char a)
{
int n = str.length;
int previous = - 1 , i;
for (i = 0 ; i < n; ++i)
{
if (str[i] == a)
{
if (i - previous > mid)
{
return false ;
}
previous = i;
}
}
if (i - previous > mid)
return false ;
else
return true ;
}
static boolean possible( char [] str, int mid)
{
for ( int i = 0 ; i < 26 ; ++i)
{
if (check(str, mid, ( char )(i + 'a' )))
return true ;
}
return false ;
}
static int findMinLength( char [] str)
{
int low = 1 , high = str.length;
while (low <= high)
{
int mid = (low + high) / 2 ;
if (possible(str, mid))
high = mid - 1 ;
else
low = mid + 1 ;
}
return high + 1 ;
}
static boolean ifAllDistinct(String str)
{
HashSet<Character> s = new HashSet<Character>();
for ( char c : str.toCharArray())
{
s.add(c);
}
return s.size() == str.length();
}
public static void main(String[] args)
{
String str = "geeksforgeeks" ;
if (ifAllDistinct(str))
System.out.print(- 1 + "\n" );
else
System.out.print(findMinLength(
str.toCharArray()));
}
}
|
Python3
def check(st, mid, a):
n = len (st)
previous = - 1
for i in range (n):
if (st[i] = = chr (a)):
if (i - previous > mid):
return False
previous = i
if (i - previous > mid):
return False
else :
return True
def possible(st, mid):
for i in range ( 26 ):
if (check(st, mid, i + ord ( 'a' ))):
return True
return False
def findMinLength(st):
low = 1
high = len (st)
while (low < = high):
mid = (low + high) / / 2
if (possible(st, mid)):
high = mid - 1
else :
low = mid + 1
return high + 1
def ifAllDistinct( st):
s = []
for c in st:
s.append(c)
return len ( set (s)) = = len (st)
if __name__ = = "__main__" :
st = "geeksforgeeks"
if (ifAllDistinct(st)):
print ( "-1" )
else :
print (findMinLength(st))
|
C#
using System;
using System.Collections.Generic;
class GFG{
static bool check( char [] str, int mid,
char a)
{
int n = str.Length;
int previous = -1, i;
for (i = 0; i < n; ++i)
{
if (str[i] == a)
{
if (i - previous > mid)
{
return false ;
}
previous = i;
}
}
if (i - previous > mid)
return false ;
else
return true ;
}
static bool possible( char [] str, int mid)
{
for ( int i = 0; i < 26; ++i)
{
if (check(str, mid, ( char )(i + 'a' )))
return true ;
}
return false ;
}
static int findMinLength( char [] str)
{
int low = 1, high = str.Length;
while (low <= high)
{
int mid = (low + high) / 2;
if (possible(str, mid))
high = mid - 1;
else
low = mid + 1;
}
return high + 1;
}
static bool ifAllDistinct(String str)
{
HashSet< char > s = new HashSet< char >();
foreach ( char c in str.ToCharArray())
{
s.Add(c);
}
return s.Count == str.Length;
}
public static void Main(String[] args)
{
String str = "geeksforgeeks" ;
if (ifAllDistinct(str))
Console.Write(-1 + "\n" );
else
Console.Write(findMinLength(
str.ToCharArray()));
}
}
|
Javascript
<script>
function check(str, mid, a)
{
var n = str.length;
var previous = -1,
i;
for (i = 0; i < n; ++i)
{
if (str[i] === a)
{
if (i - previous > mid)
{
return false ;
}
previous = i;
}
}
if (i - previous > mid)
return false ;
else
return true ;
}
function possible(str, mid)
{
for ( var i = 0; i < 26; ++i)
{
if (check(str, mid,
String.fromCharCode(
i + "a" .charCodeAt(0))))
return true ;
}
return false ;
}
function findMinLength(str)
{
var low = 1,
high = str.length;
while (low <= high)
{
var mid = parseInt((low + high) / 2);
if (possible(str, mid))
high = mid - 1;
else
low = mid + 1;
}
return high + 1;
}
function ifAllDistinct(str)
{
var s = new Array();
var temp = str.split( "" );
for (const c of temp)
{
s.push(c);
}
var set = new Set(s);
return set.size === str.length;
}
var str = "geeksforgeeks" ;
if (ifAllDistinct(str))
document.write(-1 + "<br>" );
else
document.write(
findMinLength(str.split( "" )));
</script>
|
Time Complexity : O(26 * N * log(N))
Auxiliary Space: O(1)
Like Article
Suggest improvement
Share your thoughts in the comments
Please Login to comment...