Split the given string into Odds: Digit DP
Prerequisites: Digit-DP
Given string str that represents a large number, the task is to find the minimum number of segments the given string can be divided such that each segment is an odd number in the range of 1 to 109.
Examples:
Input: str = “123456789123456789123”
Output: 3
Explanation:
The number can be divided as {123456789, 123456789, 123}
Input: str = “123456”
Output: -1
Explanation:
We can’t split the given number such that all segments are odd.
Approach: The idea is to use dynamic programming with the help of digit-dp concept to solve this problem. Therefore, a splitDP[] array is defined where splitDP[i] denotes the minimum number of splits required in the prefix string of length ‘i’ to break it into the odd subdivision.
The splitDP[] array is filled in the following way:
- A loop is used to iterate through all the indices of the given string.
- For every index ‘i’ from the above loop, another loop is iterated from 1 to 9 to check if the substring from (i + j)th index is Odd or not.
- If it forms a Odd number, then the value at splitDP[] is updated as:
splitDP[i + j] = min(splitDP[i + j], 1 + splitDP[i]);
- After updating all the values of the array, the value at the last index is the minimum number of splits for the entire string.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
bool checkOdd(string number)
{
int n = number.length();
int num = number[n - 1] - '0' ;
return (num & 1);
}
int splitIntoOdds(string number)
{
int numLen = number.length();
int splitDP[numLen + 1];
memset (splitDP, -1, sizeof (splitDP));
for ( int i = 1; i <= numLen; i++) {
if (i <= 9 && checkOdd(number.substr(0, i)))
splitDP[i] = 1;
if (splitDP[i] != -1) {
for ( int j = 1; j <= 9
&& i + j <= numLen;
j++) {
if (checkOdd(number.substr(i, j))) {
if (splitDP[i + j] == -1)
splitDP[i + j] = 1 + splitDP[i];
else
splitDP[i + j] = min(splitDP[i + j],
1 + splitDP[i]);
}
}
}
}
return splitDP[numLen];
}
int main()
{
cout << splitIntoOdds( "123456789123456789123" ) << "\n" ;
return 0;
}
|
Java
class GFG {
static int checkOdd(String number)
{
int n = number.length();
int num = number.charAt(n - 1 ) - '0' ;
return (num & 1 );
}
static int splitIntoOdds(String number)
{
int numLen = number.length();
int splitDP[] = new int [numLen + 1 ];
for ( int i= 0 ; i < numLen + 1 ; i++)
splitDP[i] = - 1 ;
for ( int i = 1 ; i <= numLen; i++) {
if (i <= 9 && (checkOdd(number.substring( 0 , i)) == 1 ))
splitDP[i] = 1 ;
if (splitDP[i] != - 1 ) {
for ( int j = 1 ; j <= 9
&& i + j <= numLen;
j++) {
if (checkOdd(number.substring(i, i + j)) == 1 ) {
if (splitDP[i + j] == - 1 )
splitDP[i + j] = 1 + splitDP[i];
else
splitDP[i + j] = Math.min(splitDP[i + j],
1 + splitDP[i]);
}
}
}
}
return splitDP[numLen];
}
public static void main (String[] args)
{
System.out.println(splitIntoOdds( "123456789123456789123" ));
}
}
|
Python3
def checkOdd(number):
n = len (number)
num = ord (number[n - 1 ]) - 48
return (num & 1 )
def splitIntoOdds(number):
numLen = len (number)
splitDP = [ - 1 for i in range (numLen + 1 )]
for i in range ( 1 , numLen + 1 ):
if (i < = 9 and checkOdd(number[ 0 :i]) > 0 ):
splitDP[i] = 1
if (splitDP[i] ! = - 1 ):
for j in range ( 1 , 10 ):
if (i + j > numLen):
break ;
if (checkOdd(number[i:i + j])):
if (splitDP[i + j] = = - 1 ):
splitDP[i + j] = 1 + splitDP[i]
else :
splitDP[i + j] = min (splitDP[i + j], 1 + splitDP[i])
return splitDP[numLen]
print (splitIntoOdds( "123456789123456789123" ))
|
C#
using System;
class GFG {
static int checkOdd( string number)
{
int n = number.Length;
int num = number[n - 1] - '0' ;
return (num & 1);
}
static int splitIntoOdds( string number)
{
int numLen = number.Length;
int []splitDP = new int [numLen + 1];
for ( int i= 0; i < numLen + 1; i++)
splitDP[i] = -1;
for ( int i = 1; i <= numLen; i++) {
if (i <= 9 && (checkOdd(number.Substring(0, i)) == 1))
splitDP[i] = 1;
if (splitDP[i] != -1) {
for ( int j = 1; j <= 9
&& i + j <= numLen;
j++) {
if (checkOdd(number.Substring(i, j)) == 1) {
if (splitDP[i + j] == -1)
splitDP[i + j] = 1 + splitDP[i];
else
splitDP[i + j] = Math.Min(splitDP[i + j],
1 + splitDP[i]);
}
}
}
}
return splitDP[numLen];
}
public static void Main ( string [] args)
{
Console.WriteLine(splitIntoOdds( "123456789123456789123" ));
}
}
|
Javascript
<script>
function checkOdd(number)
{
let n = number.length;
let num = number[n - 1] - '0' ;
return (num & 1);
}
function split intoOdds(number)
{
let numLen = number.length;
let splitDP =
Array.from({length: numLen + 1}, (_, i) => 0);
for (let i= 0; i < numLen + 1; i++)
splitDP[i] = -1;
for (let i = 1; i <= numLen; i++)
{
if (i <= 9 &&
(checkOdd(number.substr(0, i)) == 1))
splitDP[i] = 1;
if (splitDP[i] != -1) {
for (let j = 1; j <= 9
&& i + j <= numLen; j++) {
if (checkOdd(number.substr(i, i + j)) == 1)
{
if (splitDP[i + j] == -1)
splitDP[i + j] = 1 + splitDP[i];
else
splitDP[i + j] =
Math.min(splitDP[i + j],
1 + splitDP[i]);
}
}
}
}
return splitDP[numLen];
}
document.write(splitintoOdds( "123456789123456789123" ));
</script>
|
Time Complexity: O(N)
Auxiliary Space: O(numLen)
Last Updated :
09 Dec, 2021
Like Article
Save Article
Share your thoughts in the comments
Please Login to comment...