Smallest non-zero substring which has any permutation divisible by 2^K
Given a binary string S of length N and an integer K, the task is to find the smallest non-zero sub-string of S that can be jumbled to produce a binary string divisible by 2K. If no such sub-string exists then print -1. Note that K is always greater than 0.
Examples:
Input: S = “100”, k = 1
Output: 2
Smallest substring that can be jumbled is “10”.
Thus, the answer is 2.
Input: S = “1111”, k = 2
Output: -1
Approach: Let’s look at the condition of the permutation of a string being divisible by 2K.
- The string must have at least K number of 0s.
- The string must have at least one 1.
This can be implemented using two-pointer technique. For every index i, try to find the smallest index j such that the substring S[i…j-1] satisfies the above two conditions.
Let’s say the left pointer is pointing at index i and the right pointer is pointing at j and ans stores the length of the smallest required substring.
If the condition is not satisfied then increment j, else increment i.
While iterating, find the minimum (j – i) satisfying the above two conditions and update the answer as ans = min(ans, j – i).
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
int findLength(string s, int k)
{
int ans = INT_MAX;
int l = 0;
int r = 0;
int cnt_zero = 0, cnt_one = 0;
while (l < s.size() and r <= s.size()) {
if (cnt_zero >= k and cnt_one >= 1) {
ans = min(ans, r - l);
l++;
if (s[l - 1] == '0' )
cnt_zero--;
else
cnt_one--;
}
else {
if (r == s.size())
break ;
if (s[r] == '0' )
cnt_zero++;
else
cnt_one++;
r++;
}
}
if (ans == INT_MAX)
return -1;
return ans;
}
int main()
{
string s = "100" ;
int k = 2;
cout << findLength(s, k);
return 0;
}
|
Java
class GFG
{
static final int INT_MAX = Integer.MAX_VALUE;
static int findLength(String s, int k)
{
int ans = INT_MAX;
int l = 0 ;
int r = 0 ;
int cnt_zero = 0 , cnt_one = 0 ;
while (l < s.length() && r <= s.length())
{
if (cnt_zero >= k && cnt_one >= 1 )
{
ans = Math.min(ans, r - l);
l++;
if (s.charAt(l - 1 ) == '0' )
cnt_zero--;
else
cnt_one--;
}
else
{
if (r == s.length())
break ;
if (s.charAt(r) == '0' )
cnt_zero++;
else
cnt_one++;
r++;
}
}
if (ans == INT_MAX)
return - 1 ;
return ans;
}
public static void main (String[] args)
{
String s = "100" ;
int k = 2 ;
System.out.println(findLength(s, k));
}
}
|
Python3
def findLength(s, k):
ans = 10 * * 9
l = 0
r = 0
cnt_zero = 0
cnt_one = 0
while (l < len (s) and r < = len (s)):
if (cnt_zero > = k and cnt_one > = 1 ):
ans = min (ans, r - l)
l + = 1
if (s[l - 1 ] = = '0' ):
cnt_zero - = 1
else :
cnt_one - = 1
else :
if (r = = len (s)):
break
if (s[r] = = '0' ):
cnt_zero + = 1
else :
cnt_one + = 1
r + = 1
if (ans = = 10 * * 9 ):
return - 1
return ans
s = "100"
k = 2
print (findLength(s, k))
|
C#
using System;
class GFG
{
static int INT_MAX = int .MaxValue;
static int findLength( string s, int k)
{
int ans = INT_MAX;
int l = 0;
int r = 0;
int cnt_zero = 0, cnt_one = 0;
while (l < s.Length && r <= s.Length)
{
if (cnt_zero >= k && cnt_one >= 1)
{
ans = Math.Min(ans, r - l);
l++;
if (s[l - 1] == '0' )
cnt_zero--;
else
cnt_one--;
}
else
{
if (r == s.Length)
break ;
if (s[r] == '0' )
cnt_zero++;
else
cnt_one++;
r++;
}
}
if (ans == INT_MAX)
return -1;
return ans;
}
public static void Main ()
{
string s = "100" ;
int k = 2;
Console.WriteLine(findLength(s, k));
}
}
|
Javascript
<script>
function findLength(s, k)
{
var ans = 1000000000;
var l = 0;
var r = 0;
var cnt_zero = 0, cnt_one = 0;
while (l < s.length && r <= s.length) {
if (cnt_zero >= k && cnt_one >= 1) {
ans = Math.min(ans, r - l);
l++;
if (s[l - 1] == '0' )
cnt_zero--;
else
cnt_one--;
}
else {
if (r == s.length)
break ;
if (s[r] == '0' )
cnt_zero++;
else
cnt_one++;
r++;
}
}
if (ans == 1000000000)
return -1;
return ans;
}
var s = "100" ;
var k = 2;
document.write( findLength(s, k));
</script>
|
Time Complexity: O(N)
Auxiliary Space: O(1)
Last Updated :
22 Feb, 2022
Like Article
Save Article
Share your thoughts in the comments
Please Login to comment...