Skip to content
Related Articles

Related Articles

Improve Article
Save Article
Like Article

Minimum number of sub-strings of a string such that all are power of 5

  • Difficulty Level : Medium
  • Last Updated : 28 May, 2021

Given a binary string str. The task is to find the smallest positive integer C such that the binary string can be cut into C pieces (sub-strings) and each sub-string should be a power of 5 with no leading zeros.
Examples: 
 

Input: str = “101101101” 
Output:
The string “101101101” can be cut into three binary strings “101”, “101”, “101” 
each of which is a power of 5.
Input: str = “1111101” 
Output:
The string “1111101” can be cut into one binary string “1111101” which is 
125 in decimal and a power of 5.
Input: str = “00000” 
Output: -1 
Strings of only zeroes is equivalent to 0 which is not a power of 5. 
 

Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.  To complete your preparation from learning a language to DS Algo and many more,  please refer Complete Interview Preparation Course.

In case you wish to attend live classes with experts, please refer DSA Live Classes for Working Professionals and Competitive Programming Live for Students.

 



Approach: This problem is a simple variation of the longest increasing sub-sequence
Iterate from i = 1 and for every str[j…i] where j = 0 & j < i, we check if the number formed from str[j..i] is a power of 5 then we update the dp[] array with the value of the lowest possible cut size value. After confirming that the number formed from str[j..i] in decimal is a power of 5 we calculate dp[i] = min(dp[i], dp[j] + 1)
This technique is pretty similar to finding the longest increasing sub-sequence.
Below is the implementation of the above approach: 
 

C++




// C++ implementation of the approach
#include <bits/stdc++.h>
using namespace std;
#define ll unsigned long long
 
// Function that returns true
// if n is a power of 5
bool ispower(ll n)
{
    if (n < 125)
        return (n == 1 || n == 5 || n == 25);
    if (n % 125 != 0)
        return false;
    else
        return ispower(n / 125);
}
 
// Function to return the decimal
// value of binary equivalent
ll number(string s, int i, int j)
{
    ll ans = 0;
    for (int x = i; x < j; x++) {
        ans = ans * 2 + (s[x] - '0');
    }
    return ans;
}
 
// Function to return the minimum cuts required
int minCuts(string s, int n)
{
    int dp[n + 1];
 
    // Allocating memory for dp[] array
    memset(dp, n + 1, sizeof(dp));
    dp[0] = 0;
 
    // From length 1 to n
    for (int i = 1; i <= n; i++) {
 
        // If previous character is '0' then ignore
        // to avoid number with leading 0s.
        if (s[i - 1] == '0')
            continue;
        for (int j = 0; j < i; j++) {
 
            // Ignore s[j] = '0' starting numbers
            if (s[j] == '0')
                continue;
 
            // Number formed from s[j....i]
            ll num = number(s, j, i);
 
            // Check for power of 5
            if (!ispower(num))
                continue;
 
            // Assigning min value to get min cut possible
            dp[i] = min(dp[i], dp[j] + 1);
        }
    }
 
    // (n + 1) to check if all the strings are traversed
    // and no divisible by 5 is obtained like 000000
    return ((dp[n] < n + 1) ? dp[n] : -1);
}
 
// Driver code
int main()
{
    string s = "101101101";
    int n = s.length();
    cout << minCuts(s, n);
 
    return 0;
}

Java




// Java implementation of the approach
import java.util.*;
 
class GFG
{
 
    // Function that returns true
    // if n is a power of 5
    static boolean ispower(long n)
    {
        if (n < 125)
        {
            return (n == 1 || n == 5 || n == 25);
        }
        if (n % 125 != 0)
        {
            return false;
        }
        else
        {
            return ispower(n / 125);
        }
    }
 
    // Function to return the decimal
    // value of binary equivalent
    static long number(String s, int i, int j)
    {
        long ans = 0;
        for (int x = i; x < j; x++)
        {
            ans = ans * 2 + (s.charAt(x) - '0');
        }
        return ans;
    }
 
    // Function to return the minimum cuts required
    static int minCuts(String s, int n)
    {
        int[] dp = new int[n + 1];
 
        // Alongocating memory for dp[] array
        Arrays.fill(dp, n+1);
        dp[0] = 0;
 
        // From length 1 to n
        for (int i = 1; i <= n; i++)
        {
 
            // If previous character is '0' then ignore
            // to avoid number with leading 0s.
            if (s.charAt(i - 1) == '0')
            {
                continue;
            }
            for (int j = 0; j < i; j++)
            {
 
                // Ignore s[j] = '0' starting numbers
                if (s.charAt(j) == '0')
                {
                    continue;
                }
 
                // Number formed from s[j....i]
                long num = number(s, j, i);
 
                // Check for power of 5
                if (!ispower(num))
                {
                    continue;
                }
 
                // Assigning min value to get min cut possible
                dp[i] = Math.min(dp[i], dp[j] + 1);
            }
        }
 
        // (n + 1) to check if all the Strings are traversed
        // and no divisible by 5 is obtained like 000000
        return ((dp[n] < n + 1) ? dp[n] : -1);
    }
 
    // Driver code
    public static void main(String[] args)
    {
        String s = "101101101";
        int n = s.length();
        System.out.println(minCuts(s, n));
    }
}
 
// This code is contributed by 29AjayKumar

Python 3




# Python 3 implementation of the approach
  
# Function that returns true
# if n is a power of 5
def ispower( n):
    if (n < 125):
        return (n == 1 or n == 5 or n == 25)
    if (n % 125 != 0):
        return 0
    else:
        return ispower(n // 125)
 
  
# Function to return the decimal
# value of binary equivalent
def number(s, i, j):
    ans = 0
    for x in range( i, j) :
        ans = ans * 2 + (ord(s[x]) - ord('0'))
    return ans
 
# Function to return the minimum cuts required
def minCuts(s, n):
  
    # Allocating memory for dp[] array
    dp=[n+1 for i in range(n+1)]
    dp[0] = 0;
  
    # From length 1 to n
    for i in range(1, n+1) :
  
        # If previous character is '0' then ignore
        # to avoid number with leading 0s.
        if (s[i - 1] == '0'):
            continue
        for j in range(i) :
  
            # Ignore s[j] = '0' starting numbers
            if (s[j] == '0'):
                continue
  
            # Number formed from s[j....i]
            num = number(s, j, i)
  
            # Check for power of 5
            if (not ispower(num)):
                continue
  
            # Assigning min value to get min cut possible
            dp[i] = min(dp[i], dp[j] + 1)
  
    # (n + 1) to check if all the strings are traversed
    # and no divisible by 5 is obtained like 000000
    if dp[n] < n + 1:
        return dp[n]
    else:
        return  -1
  
# Driver code
if __name__== "__main__":
    s = "101101101"
    n = len(s)
    print(minCuts(s, n))
 
# This code is contributed by ChitraNayal

C#




// C# implementation of the approach
using System;
 
class GFG
{
 
    // Function that returns true
    // if n is a power of 5
    static Boolean ispower(long n)
    {
        if (n < 125)
        {
            return (n == 1 || n == 5 || n == 25);
        }
        if (n % 125 != 0)
        {
            return false;
        }
        else
        {
            return ispower(n / 125);
        }
    }
 
    // Function to return the decimal
    // value of binary equivalent
    static long number(String s, int i, int j)
    {
        long ans = 0;
        for (int x = i; x < j; x++)
        {
            ans = ans * 2 + (s[x] - '0');
        }
        return ans;
    }
 
    // Function to return the minimum cuts required
    static int minCuts(String s, int n)
    {
        int[] dp = new int[n + 1];
 
        // Alongocating memory for dp[] array
        for (int i = 0; i <= n; i++)
            dp[i]=n+1;
        dp[0] = 0;
 
        // From length 1 to n
        for (int i = 1; i <= n; i++)
        {
 
            // If previous character is '0' then ignore
            // to avoid number with leading 0s.
            if (s[i - 1] == '0')
            {
                continue;
            }
            for (int j = 0; j < i; j++)
            {
 
                // Ignore s[j] = '0' starting numbers
                if (s[j] == '0')
                {
                    continue;
                }
 
                // Number formed from s[j....i]
                long num = number(s, j, i);
 
                // Check for power of 5
                if (!ispower(num))
                {
                    continue;
                }
 
                // Assigning min value to get min cut possible
                dp[i] = Math.Min(dp[i], dp[j] + 1);
            }
        }
 
        // (n + 1) to check if all the Strings are traversed
        // and no divisible by 5 is obtained like 000000
        return ((dp[n] < n + 1) ? dp[n] : -1);
    }
 
    // Driver code
    public static void Main(String[] args)
    {
        String s = "101101101";
        int n = s.Length;
        Console.WriteLine(minCuts(s, n));
    }
}
 
/* This code contributed by PrinciRaj1992 */

PHP




<?php
// PHP implementation of the approach
 
// Function that returns true
// if n is a power of 5
function ispower($n)
{
    if ($n < 125)
        return ($n == 1 || $n == 5 || $n == 25);
    if ($n % 125 != 0)
        return false;
    else
        return ispower($n / 125);
}
 
// Function to return the decimal
// value of binary equivalent
function number($s, $i, $j)
{
    $ans = 0;
    for ($x = $i; $x < $j; $x++)
    {
        $ans = $ans * 2 + (ord($s[$x]) - ord('0'));
    }
    return $ans;
}
 
// Function to return the minimum cuts required
function minCuts($s, $n)
{
    // Allocating memory for dp[] array
    $dp = array_fill(0,$n + 1,$n + 1);
     
    $dp[0] = 0;
 
    // From length 1 to n
    for ($i = 1; $i <= $n; $i++)
    {
 
        // If previous character is '0' then ignore
        // to avoid number with leading 0s.
        if ($s[$i - 1] == '0')
            continue;
        for ($j = 0; $j < $i; $j++)
        {
 
            // Ignore s[j] = '0' starting numbers
            if ($s[$j] == '0')
                continue;
 
            // Number formed from s[j....i]
            $num = number($s, $j, $i);
 
            // Check for power of 5
            if (!ispower($num))
                continue;
 
            // Assigning min value to get min cut possible
            $dp[$i] = min($dp[$i], $dp[$j] + 1);
        }
    }
 
    // (n + 1) to check if all the strings are traversed
    // and no divisible by 5 is obtained like 000000
    return (($dp[$n] < $n + 1) ? $dp[$n] : -1);
}
 
    // Driver code
    $s = "101101101";
    $n = strlen($s);
    echo minCuts($s, $n);
 
    // This code is contributed by AnkitRai01
 
?>

Javascript




<script>
 
// Javascript implementation of the approach
 
// Function that returns true
// if n is a power of 5
function ispower(n)
{
    if (n < 125)
        return (n == 1 || n == 5 || n == 25);
    if (n % 125 != 0)
        return false;
    else
        return ispower(parseInt(n / 125));
}
 
// Function to return the decimal
// value of binary equivalent
function number(s, i, j)
{
    var ans = 0;
    for (var x = i; x < j; x++) {
        ans = ans * 2 + (s[x] - '0');
    }
    return ans;
}
 
// Function to return the minimum cuts required
function minCuts(s, n)
{
    var dp = Array(n+1).fill(n+1);
    dp[0] = 0;
 
    // From length 1 to n
    for (var i = 1; i <= n; i++) {
 
        // If previous character is '0' then ignore
        // to avoid number with leading 0s.
        if (s[i - 1] == '0')
            continue;
        for (var j = 0; j < i; j++) {
 
            // Ignore s[j] = '0' starting numbers
            if (s[j] == '0')
                continue;
 
            // Number formed from s[j....i]
            var num = number(s, j, i);
 
            // Check for power of 5
            if (!ispower(num))
                continue;
 
            // Assigning min value to get min cut possible
            dp[i] = Math.min(dp[i], dp[j] + 1);
        }
    }
 
    // (n + 1) to check if all the strings are traversed
    // and no divisible by 5 is obtained like 000000
    return ((dp[n] < n + 1) ? dp[n] : -1);
}
 
// Driver code
var s = "101101101";
var n = s.length;
document.write( minCuts(s, n));
 
</script>
Output: 
3

 

Time complexity: O(n2
Space complexity: O(n)
 




My Personal Notes arrow_drop_up
Recommended Articles
Page :

Start Your Coding Journey Now!