Reputation: 783
I am trying to solve a problem where I want to find the max product of any 3 integers in an array.
I tried my solution:
def maximumProduct(nums):
"""
:type nums: List[int]
:rtype: int
"""
list_of_ints = nums
t = sorted(list_of_ints[:4])
max_pos = t[2]
max_pos_2 = t[1]
max_pos_3 = t[0]
min_neg = 0
min_neg_2 = 0
for x in list_of_ints[3:]:
if x<0 and x< min_neg:
temp = min_neg
min_neg = x
min_neg_2 = temp
elif x<0 and x<min_neg_2:
min_neg_2 = x
if x>0 and x>max_pos:
temp = max_pos
max_pos = x
temp2 = max_pos_2
max_pos_2 = temp
max_pos_3 = temp2
elif x>0 and x>max_pos_2:
temp = max_pos_2
max_pos_2 = x
max_pos_3 = temp
elif x>0 and x>max_pos_3:
max_pos_3 = x
return max(max_pos*max_pos_2*max_pos_3, min_neg*min_neg_2*max_pos)
The above solution fails on input nums = [-1, -2, -3]
. The expected output is -6
, the output of the program is 0
.
This is due to the initialization of min_neg
and min_neg_1
to zero.
How to initialize to avoid this issue? I always have trouble setting up the right initializations.
Upvotes: 1
Views: 1676
Reputation: 1
I tried kfx's O(n) solution but it was not taking into account possible negative ints for me. I added a few lines to adjust for that, and also two more possible combinations and it worked. Correct me if I am wrong but I think this is still O(n) notation right?
def maximum_product(nums):
max3 = heapq.nlargest(3, nums)
min3 = heapq.nsmallest(3, nums)
a1 = max3[0] * max3[1] * max3[2]
a2 = min3[0] * min3[1] * min3[2]
a3 = min3[0] * max3[0] * max3[1]
a4 = min3[0] * min3[1] * max3[0]
if abs(min(a1, a2, a3, a4)) > abs(max(a1, a2, a3, a4)):
return min(a1, a2, a3, a4)
else:
return max(a1, a2, a3, a4)
Upvotes: 0
Reputation: 8537
To solve this kind of exercise efficiently, you need to recognize that there are only a few possible cases. Focus on the signs of the numbers and think what would be the sign of the result:
+ * + * + = + (good)
+ * + * - = - (bad)
+ * - * - = + (good)
- * - * - = - (bad)
anything * 0 = 0 (neutral)
So, if the list has both negative and negative numbers, the answer is either the product of the three largest numbers, or the product the two smallest (negative) numbers and the largest number (positive).
If this condition is not true, the answer must be the product of the largest numbers in the array.
So, the answer has to take either the three last elements in the array after sorting, or the two first ones and the last one, and multiply them together. The simplest and most elegant way to do it is to first sort the list of numbers:
def maximum_product(nums): # O(n log(n)) solution
nums.sort()
assert len(nums) >= 3 # assume the input has been validated
a1 = nums[-1] * nums[-2] * nums[-3]
a2 = nums[0] * nums[1] * nums[-1]
return max(a1, a2)
However, you can also find the maximal three and the minimal two numbers in O(n) time. One efficient approach how to find the maximum N
numbers in a container is to keep a heap of size N
while iterating through it. At the end, the heap contains the answer: a partially sorted list of N
largest elements.
Python module heapq
offers convenient API for this: the functions nlargest()
and nsmallest()
. So here we go:
import heapq
def maximum_product(nums): # O(n) solution
assert len(nums) >= 3 # assume the input has been validated
max3 = heapq.nlargest(3, nums)
min2 = heapq.nsmallest(2, nums)
a1 = max3[0] * max3[1] * max3[2]
a2 = min2[0] * min2[1] * max(max3)
return max(a1, a2)
Upvotes: 5
Reputation: 123541
You can use itertools.combinations
to make doing it very easy. What you're calling an "array" is referred to as a "list" in Python, by-the-way.
from itertools import combinations
def maximum_product(nums):
return max(trio[0] * trio[1] * trio[2] for trio in combinations(nums, 3))
nums = [-1, -2, -3, 9]
print(maximum_product(nums)) # -> 54
This could be generalized to determine the maximum product of N integers by (also) using functools.reduce()
to compute the product of N items:
from functools import reduce
from itertools import combinations
def maximum_product(nums, group_size):
return max(reduce(lambda a, b: a*b, nums, 1)
for group in combinations(nums, group_size))
nums = [-1, -2, -3, 9]
print(maximum_product(nums, 3)) # -> 54
Of course, this generality will slow execution down a bit...
Upvotes: 1
Reputation: 4814
Try this:
arr = sorted(list_of_ints)
def getMax(t):
maxP = t[0] * t[1] * t[2]
i = 0
while t[i] > -1:
i += 1
maxN = t[i] * t[i + 1] * t[0]
return max(maxP, maxN)
print(getMax(arr))
Upvotes: 0
Reputation: 56
You can initialize to negative infinity: min_neg = float('-inf')
Upvotes: 2