This was an interview question I had and I was embarrassingly pretty stumped by it. Wanted to know if anyone could think up an answer to it and provide the big O notation for it
Here's an iterative dynamic programming solution.
As opposed to the recursive version (which should have a similar running time).
The basic idea:
A[position][count]
is the highest number that can be obtained ending at position position
, using count
multiplications.
So:
A[position][count] = max(for i = 0 to position
A[i][count-1] * input.substring(i, position))
Do this for each position and each count, then multiply each of these at the required number of multiplications with the entire remaining string.
Complexity:
Given a string |s|
with m
multiplication operators to be inserted...
O(m|s|2g(s))
where g(s)
is the complexity of multiplication.
Java code:
static long solve(String digits, int multiplications)
{
if (multiplications == 0)
return Long.parseLong(digits);
// Preprocessing - set up substring values
long[][] substrings = new long[digits.length()][digits.length()+1];
for (int i = 0; i < digits.length(); i++)
for (int j = i+1; j <= digits.length(); j++)
substrings[i][j] = Long.parseLong(digits.substring(i, j));
// Calculate multiplications from the left
long[][] A = new long[digits.length()][multiplications+1];
A[0][0] = 1;
for (int i = 1; i < A.length; i++)
{
A[i][0] = substrings[0][i];
for (int j = 1; j < A[0].length; j++)
{
long max = -1;
for (int i2 = 0; i2 < i; i2++)
{
long l = substrings[i2][i];
long prod = l * A[i2][j-1];
max = Math.max(max, prod);
}
A[i][j] = max;
}
}
// Multiply left with right and find maximum
long max = -1;
for (int i = 1; i < A.length; i++)
{
max = Math.max(max, substrings[i][A.length] * A[i][multiplications]);
}
return max;
}
A very basic test:
System.out.println(solve("99287", 1));
System.out.println(solve("99287", 2));
System.out.println(solve("312", 1));
Prints:
86304
72036
62
Yes, it just prints the maximum. It's not too difficult to have it actually print the sums, if required.