Given an array of integers, which can contain both +ve and -ve numbers. I've to maximize the product of any 3 elements of the array. The elements can be non-contiguous.
Some examples:
int[] arr = {-5, -7, 4, 2, 1, 9}; // Max Product of 3 numbers = -5 * -7 * 9
int[] arr2 = {4, 5, -19, 3}; // Max Product of 3 numbers = 4 * 5 * 3
I've tried solving it using Dynamic Programming, but I'm not getting the expected result. It is returning the result often involving the same number twice in the multiplication. So, for the array - {4, 2, 1, 9}
, it is returning - 32
, which is 4 * 4 * 2
.
Here's my code:
public static int maxProduct(int[] arr, int count) {
return maxProduct(arr, 0, arr.length - 1, count);
}
private static int maxProduct(int[] arr, int fromIndex, int toIndex, int count) {
if (count == 1) {
return maximum(arr, fromIndex, toIndex);
} else if (toIndex - fromIndex + 1 < count) {
return 1;
} else {
return MathUtil.max(maxProduct(arr, fromIndex, toIndex - 1, count - 1) * arr[toIndex - 1],
maxProduct(arr, fromIndex, toIndex - 1, count));
}
}
MathUtil.max(int a, int b)
is a method that gives maximum ofa
andb
.- The two values I pass to
max
method there are:maxProduct
, when we consider last element as a part of product.maxProduct
, when we don't consider it as a part of product.
count
contains the number of element we want to consider. Here3
.- For
count == 1
, we have to find maximum of 1 element from array. That means, we have to use maximum array element. - If
toIndex - fromIndex + 1 < count
, means, there are not enough elements in the array between those indices.
I've an intuition that, the first if
condition is one of the reason of failure. Because, it is only considering maximum element from an array, while the maximum product may comprise of negative numbers too. But I don't know how to take care of that.
The reason I'm using Dynamic Programming is that I can then generalize this solution to work for any value of count
. Of course, if someone have any better approach, even for count = 3
, I welcome the suggestion (I would want to avoid sorting the array, as that will be another O(nlogn)
at the least).
https://stackoverflow.com/users/2466168/maandoo 's answer is the best.
As, he said, answer is
max(l,r)
forLet me elaborate now.
I think this problem is confusion because each number can be positive, negative and zero. 3 state is annoying to mange by programming, you know!
Case 1) Given three numbers
Case 2) Given four numbers
+
, Negative number is show-
.Case 2-1)
When a 0 is mixed in four numbers, it comes between
-
and+
.Case 2-2) Suppose smallest
+
was actually 0.Case 2-3)
Suppose largest
-
was actually 0.Case 2-4)
If more than two 0 is mixed, products becomes always 0 because
Summary for Case 2)
answer is consistent among Case 2-1 ~ 2-4.
So, we do not need to worry about 0 actually.
Case 3) More than four numbers
For count=3, your solution will have 1 of 3 forms:
The 3 largest positive values (assuming there ARE 3 positive values)
The largest positive value and the 2 smallest negative values (assuming there IS a positive value)
The 3 least negative values
Each of which can be solved a lot easier than using DP.
Language - C#
Greedy Approach
Thanks to interviewcake.com
Detailed Explanation of this Algorithm
in JavaScript
Sort The Array
Then max will be either the product of last 3 or first 2(if negative) and the last.