Maximum Product of Three Numbers LT628
Given an integer array, find three numbers whose product is maximum and output the maximum product.
Example 1:
Input: [1,2,3] Output: 6
Example 2:
Input: [1,2,3,4] Output: 24
Note:
- The length of the given array will be in range [3,104] and all elements are in the range [-1000, 1000].
- Multiplication of any three numbers in the input won't exceed the range of 32-bit signed integer.
Idea 1. Bruteforce, three cases: (1)all positive max1 * max2 * max3 (2) all negative, 0 or negMax1 * negMax2 *negMax3 (3) otherwise, Math.max(max1* max2 * max3, negMin1 * negMax2*max1)
Time complexity: O(n)
Space complexity: O(1), 8 variables
1 class Solution { 2 public int maximumProduct(int[] nums) { 3 int posMax = -1; 4 int posSecondMax = -1; 5 int posThirdMax = -1; 6 7 int negMin = 1; 8 int negSecondMin = 1; 9 10 int negMax = 1; 11 int negSecondMax = 1; 12 int negThirdMax = 1; 13 14 boolean hasZero = false; 15 16 for(int num: nums) { 17 if(num >= 0) { 18 if(num == 0) { 19 hasZero = true; 20 } 21 22 if(num > posMax) { 23 posThirdMax = posSecondMax; 24 posSecondMax = posMax; 25 posMax = num; 26 } 27 else if(num > posSecondMax) { 28 posThirdMax = posSecondMax; 29 posSecondMax = num; 30 } 31 else if(num > posThirdMax) { 32 posThirdMax = num; 33 } 34 } 35 else if(num < 0) { 36 37 if(negMax == 1 || num > negMax) { 38 negThirdMax = negSecondMin; 39 negSecondMax = negMax; 40 negMax = num; 41 } 42 else if(negSecondMax == 1 || num > negSecondMax) { 43 negThirdMax = negSecondMax; 44 negSecondMax = num; 45 } 46 else if(negThirdMax == 1 || num > negThirdMax) { 47 negThirdMax = num; 48 } 49 50 if(num < negMin) { 51 negSecondMin = negMin; 52 negMin = num; 53 } 54 else if(num < negSecondMin) { 55 negSecondMin = num; 56 } 57 } 58 } 59 60 if(posMax == -1) { 61 if(hasZero) { 62 return 0; 63 } 64 else { 65 return negMax * negSecondMax * negThirdMax; 66 } 67 } 68 else if(negMax == 1) { 69 return posMax * posSecondMax * posThirdMax; 70 } 71 else { 72 return Math.max(negMin * negSecondMin* posMax, posMax * posSecondMax * posThirdMax); 73 } 74 } 75 }
Idea 1.b. Instead just need 5 variables, the two smallest values(min1 and min2), and three largest (max1, max2 and max3) determins the maximum product of three numbers Math.max(max1 * max2 * max3, min1*min2*max1)
Time complexity: O(N)
Space complexity: O(1)
1 class Solution { 2 public int maximumProduct(int[] nums) { 3 int max = Integer.MIN_VALUE; 4 int secondMax = Integer.MIN_VALUE; 5 int thirdMax = Integer.MIN_VALUE; 6 7 int min = Integer.MAX_VALUE; 8 int secondMin = Integer.MAX_VALUE; 9 10 11 for(int num: nums) { 12 if(num > max) { 13 thirdMax = secondMax; 14 secondMax = max; 15 max = num; 16 } 17 else if(num > secondMax) { 18 thirdMax = secondMax; 19 secondMax = num; 20 } 21 else if(num > thirdMax) { 22 thirdMax = num; 23 } 24 25 if(num < min) { 26 secondMin = min; 27 min = num; 28 } 29 else if(num < secondMin) { 30 secondMin = num; 31 } 32 } 33 34 return Math.max(max * secondMax * thirdMax, max * min * secondMin); 35 } 36 }
Idea 2. Sort, sort is a good start if you have no clue
Time complexity: O(NlogN)
Space complexity: O(logN) the depth of recursive call tree, worse case O(N)
1 class Solution { 2 public int maximumProduct(int[] nums) { 3 int n = nums.length; 4 Arrays.sort(nums); 5 6 return Math.max(nums[n-1] * nums[n-2] * nums[n-3], nums[n-1] * nums[0] * nums[1]); 7 } 8 }
Idea 2.b use minHeap to get the max 3 elements, maxHeap to get the min 2 elements
Time complexity: O(NLogK), K = 3
Space complexity: O(K)
1 class Solution { 2 public int maximumProduct(int[] nums) { 3 int n = nums.length; 4 PriorityQueue<Integer> minHeap = new PriorityQueue<>(); 5 PriorityQueue<Integer> maxHeap = new PriorityQueue<>((a, b) -> Integer.compare(b, a)); 6 7 for(int num: nums) { 8 minHeap.add(num); 9 if(minHeap.size() > 3) { 10 minHeap.poll(); 11 } 12 13 maxHeap.add(num); 14 if(maxHeap.size() > 2) { 15 maxHeap.poll(); 16 } 17 } 18 19 int max3 = minHeap.poll(); 20 int max2 = minHeap.poll(); 21 int max1 = minHeap.poll(); 22 23 int min2 = maxHeap.poll(); 24 int min1 = maxHeap.poll(); 25 26 return Math.max(max1 * max2 * max3, max1 * min1 * min2); 27 } 28 }