Minimum splits in a binary string such that every substring is a power of 4 or 6.
Last Updated :
19 Aug, 2022
Given a string S composed of 0 and 1. Find the minimum splits such that the substring is a binary representation of the power of 4 or 6 with no leading zeros. Print -1 if no such partitioning is possible.
Examples:
Input: 100110110
Output: 3
The string can be split into a minimum of
three substrings 100(power of 4), 110
(power of 6) and 110(power of 6).
Input : 00000
Output : -1
0 is not a power of 4 or 6.
A simple solution is to split the string recursively at different indices and check if each split is a power of 4 or 6. Start with index 0 and split str[0] from other string. If it is a power of 4 or 6 then call recursively for index 1 and perform the same operation. When an entire string is split check if a total number of partitions are minimum so far or not. Then split str[0..1], check if it is the power of 4 or 6 and then call recursively for rest string. Compare partitions with minimum so far at the end of string traversal. This approach will be exponential in time.
An efficient solution is to use Dynamic Programming. A 1-D dp table is created in which dp[i] stores minimum number of partitions required to split string str[i..n-1] into substrings that are power of 4 or 6. Suppose we are at index i and str[i..j] is power of 4 or 6, then minimum number of partitions will be minimum number of partitions to split str[j+1..n-1] plus one partition to split str[i..j] from string, that is dp[j+1] + 1. Hence the recurrence relation for (j!=(n-1)) and (dp[j + 1]!=-1) will be:
dp[i] = min(dp[i], dp[j + 1] + 1)
Implementation:
C++
#include <bits/stdc++.h>
using namespace std;
bool isPowerOf( long val, int base)
{
while (val > 1) {
if (val % base != 0)
return false ;
val /= base;
}
return true ;
}
int numberOfPartitions(string binaryNo)
{
int i, j, n = binaryNo.length();
long val;
int dp[n];
dp[n - 1] = ((binaryNo[n - 1] - '0' ) == 0) ? -1 : 1;
for (i = n - 2; i >= 0; i--) {
val = 0;
if ((binaryNo[i] - '0' ) == 0) {
dp[i] = -1;
continue ;
}
dp[i] = INT_MAX;
for (j = i; j < n; j++) {
val = (val * 2) + ( long )(binaryNo[j] - '0' );
if (isPowerOf(val, 4) || isPowerOf(val, 6)) {
if (j == n - 1) {
dp[i] = 1;
}
else {
if (dp[j + 1] != -1)
dp[i] = min(dp[i], dp[j + 1] + 1);
}
}
}
if (dp[i] == INT_MAX)
dp[i] = -1;
}
return dp[0];
}
int main()
{
string binaryNo = "100110110" ;
cout << numberOfPartitions(binaryNo);
return 0;
}
|
Java
import java.io.*;
class GFG
{
static boolean isPowerOf( long val,
int base)
{
while (val > 1 )
{
if (val % base != 0 )
return false ;
val /= base;
}
return true ;
}
static int numberOfPartitions(String binaryNo)
{
int i, j, n = binaryNo.length();
long val;
int dp[] = new int [n];
dp[n - 1 ] = (((binaryNo.charAt(n - 1 ) -
'0' ) == 0 ) ?
- 1 : 1 );
for (i = n - 2 ; i >= 0 ; i--)
{
val = 0 ;
if ((binaryNo.charAt(i) - '0' ) == 0 )
{
dp[i] = - 1 ;
continue ;
}
dp[i] = Integer.MAX_VALUE;
for (j = i; j < n; j++)
{
val = (val * 2 ) +
( long )(binaryNo.charAt(j) - '0' );
if (isPowerOf(val, 4 ) ||
isPowerOf(val, 6 ))
{
if (j == n - 1 )
{
dp[i] = 1 ;
}
else
{
if (dp[j + 1 ] != - 1 )
dp[i] = Math.min(dp[i],
dp[j + 1 ] + 1 );
}
}
}
if (dp[i] == Integer.MAX_VALUE)
dp[i] = - 1 ;
}
return dp[ 0 ];
}
public static void main (String[] args)
{
String binaryNo = "100110110" ;
System.out.println(numberOfPartitions(binaryNo));
}
}
|
Python 3
import sys
def isPowerOf(val, base):
while (val > 1 ):
if (val % base ! = 0 ):
return False
val / / = base
return True
def numberOfPartitions(binaryNo):
n = len (binaryNo)
dp = [ 0 ] * n
if (( ord (binaryNo[n - 1 ]) - ord ( '0' )) = = 0 ) :
dp[n - 1 ] = - 1
else :
dp[n - 1 ] = 1
for i in range ( n - 2 , - 1 , - 1 ):
val = 0
if (( ord (binaryNo[i]) - ord ( '0' )) = = 0 ):
dp[i] = - 1
continue
dp[i] = sys.maxsize
for j in range (i, n):
val = (val * 2 ) + ( ord (binaryNo[j]) - ord ( '0' ))
if (isPowerOf(val, 4 ) or isPowerOf(val, 6 )):
if (j = = n - 1 ):
dp[i] = 1
else :
if (dp[j + 1 ] ! = - 1 ):
dp[i] = min (dp[i], dp[j + 1 ] + 1 )
if (dp[i] = = sys.maxsize):
dp[i] = - 1
return dp[ 0 ]
if __name__ = = "__main__" :
binaryNo = "100110110"
print (numberOfPartitions(binaryNo))
|
C#
using System;
class GFG
{
static bool isPowerOf( long val, int b)
{
while (val > 1)
{
if (val % b != 0)
return false ;
val /= b;
}
return true ;
}
static int numberOfPartitions( string binaryNo)
{
int i, j, n = binaryNo.Length;
long val;
int [] dp = new int [n];
dp[n - 1] = (((binaryNo[n - 1] -
'0' ) == 0) ?
-1 : 1);
for (i = n - 2; i >= 0; i--)
{
val = 0;
if ((binaryNo[i] - '0' ) == 0)
{
dp[i] = -1;
continue ;
}
dp[i] = int .MaxValue;
for (j = i; j < n; j++)
{
val = (val * 2) +
( long )(binaryNo[j] - '0' );
if (isPowerOf(val, 4) ||
isPowerOf(val, 6))
{
if (j == n - 1)
{
dp[i] = 1;
}
else
{
if (dp[j + 1] != -1)
dp[i] = Math.Min(dp[i],
dp[j + 1] + 1);
}
}
}
if (dp[i] == int .MaxValue)
dp[i] = -1;
}
return dp[0];
}
public static void Main ()
{
string binaryNo = "100110110" ;
Console.Write(numberOfPartitions(binaryNo));
}
}
|
Javascript
<script>
function isPowerOf(val, base)
{
while (val > 1) {
if (val % base != 0)
return false ;
val /= base;
}
return true ;
}
function numberOfPartitions(binaryNo)
{
var i, j, n = binaryNo.length;
var val;
var dp = Array(n);
dp[n - 1] = ((binaryNo[n - 1] - '0' ) == 0) ? -1 : 1;
for (i = n - 2; i >= 0; i--) {
val = 0;
if ((binaryNo[i] - '0' ) == 0) {
dp[i] = -1;
continue ;
}
dp[i] = 1000000000;
for (j = i; j < n; j++) {
val = (val * 2) + (binaryNo[j] - '0' );
if (isPowerOf(val, 4) || isPowerOf(val, 6)) {
if (j == n - 1) {
dp[i] = 1;
}
else {
if (dp[j + 1] != -1)
dp[i] = Math.min(dp[i], dp[j + 1] + 1);
}
}
}
if (dp[i] == 1000000000)
dp[i] = -1;
}
return dp[0];
}
var binaryNo = "100110110" ;
document.write( numberOfPartitions(binaryNo));
</script>
|
Complexity Analysis:
- Time Complexity: O(n^2*log(x)), x = largest power of 4 or 6 obtainable from input string.
- Auxiliary Space: O(n)
Like Article
Suggest improvement
Share your thoughts in the comments
Please Login to comment...