leetcode#628 Maximum Product of Three Numbers
Given an integer array, find three numbers whose product is maximum and output the maximum product.
Example 1:
1 2 3 4
| >Input: [1,2,3] >Output: 6 > >
|
>
Example 2:
1 2 3 4
| >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.
解释
给定一个整数数组,要求找到三个元素,使得这三个元素的乘积最大,输出最大的乘积值。
- 给定数组的大小范围为:[3,104],元素的范围为:[-1000,1000];
- 上述给定的范围保证了任意三个元素的乘积不会溢出32位的整型范围。
我的解法
意思不就是…找出数组中最大的三个数么?找到之后,让他们三个相乘,输出结果即可。
使用一个自带排序的数据结构,比如PriorityQueue(不能用Set,可能会有重复的元素),维持三个元素的大小,遍历所有元素,不断利用大的替换队列中小的元素,最终剩下的三个元素就是数组中最大的三个元素。
需要注意一点的是,可能会有负数,如果有偶数个负数相乘,就不能单纯让三个最大的元素相乘得结果了。
那么可以这么做:先对数组进行排序,从小到大,绝对值最大的两个负数(如果有的话),就会存在数组的头部两位,数组中最大的三个数,会存在数组的尾部三位,所以需要比较两个乘积:数组后三位的乘积,数组前两位与数组最后一位的乘积。
解法一:没有考虑数组中存在负数,单纯取数组中最大的三个数进行相乘。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| class Solution { public int maximumProduct(int[] nums) { int res = 1; if(nums.length == 3) { for(int num : nums) { res *= num; } } else { PriorityQueue<Integer> queue = new PriorityQueue<Integer>(); for(int num : nums) { queue.add(num); if(queue.size() == 4) queue.poll(); } for(int i = 0; i < 3; i++) { res *= queue.poll(); } } return res; } }
|
解法二:先排序,后获取两个乘积值。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| class Solution { public int maximumProduct(int[] nums) { int res = 1; if(nums.length == 3) { for(int num : nums) { res *= num; } } else { Arrays.sort(nums); int tmp1 = nums[0]*nums[1]*nums[nums.length-1]; int tmp2 = nums[nums.length-1]*nums[nums.length-2]*nums[nums.length-3]; res = tmp1 > tmp2 ? tmp1 : tmp2; } return res; } }
|
大神解法
解法一:先排序,后获取两个乘积值。
1 2 3 4 5 6 7 8
| public int maximumProduct(int[] nums) { Arrays.sort(nums); //One of the Three Numbers is the maximum value in the array. int a = nums[nums.length - 1] * nums[nums.length - 2] * nums[nums.length - 3]; int b = nums[0] * nums[1] * nums[nums.length - 1]; return a > b ? a : b; }
|
解法二:声势浩大的插入排序,只不过这个排序维持的只有最小的两个数和最大的三个数——所以思想是一样的:找到最小的两个数(考虑到有负数的情况,且可能绝对值较大)和最大三个数,再比较这两种乘积的大小。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| public int maximumProduct(int[] nums) { int max1 = Integer.MIN_VALUE, max2 = Integer.MIN_VALUE, max3 = Integer.MIN_VALUE, min1 = Integer.MAX_VALUE, min2 = Integer.MAX_VALUE; for (int n : nums) { if (n > max1) { max3 = max2; max2 = max1; max1 = n; } else if (n > max2) { max3 = max2; max2 = n; } else if (n > max3) { max3 = n; } if (n < min1) { min2 = min1; min1 = n; } else if (n < min2) { min2 = n; } } return Math.max(max1*max2*max3, max1*min1*min2); }
|