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.
分析:题目要求给一个数组,求出这个数组三个数字乘积的最大值。乍一看比较简单,就是找出最大的三个数字就行了。但是其中暗藏杀机。
1、有0的情况如何处理
2、有负数的情况,比如1,-2,-3,4。乘积最大的是24.
因此这里要比较两个值的大小,最小的两个值*最大值 and 最大的三个值乘积
下面思路就比较简单了,找出这五个值就可以了。java代码如下:
1 class Solution { 2 public int maximumProduct(int[] nums) { 3 if (nums.length == 3) return nums[0]*nums[1]*nums[2]; 4 int max1 = Integer.MIN_VALUE,max2=Integer.MIN_VALUE,max3=Integer.MIN_VALUE,min1=Integer.MAX_VALUE,min2=Integer.MAX_VALUE; 5 int ans=0; 6 for ( int n : nums ){ 7 if ( n > max1 ){ 8 max3 = max2; 9 max2 = max1; 10 max1 = n; 11 }else if ( n > max2 ){ 12 max3 = max2; 13 max2 = n; 14 }else if ( n > max3 ){ 15 max3 = n; 16 } 17 18 if ( n < min1 ){ 19 min2 = min1; 20 min1 = n; 21 }else if ( n < min2 ){ 22 min2 = n; 23 } 24 } 25 return Math.max(max1*max2*max3,max1*min1*min2); 26 } 27 }
运行时间7ms,应该是目前最快的方法了。
这题目还可以提炼出这个知识点:如何在数组中找到前k个大(小)的数组。----------------联想到 第k大(小)数字。
如果是第k大数字,建立k个元素的最小堆,然后不停的用数组中剩下的与堆顶比较。
如果是第k小数字,建立k个元素的最大堆(建立最大堆需要重写compare方法),方法与上面类似。
那么其实这些堆中就保存着前k大(小)的数字。当然这是一种方法求解,但是比较浪费时间,在数字非常多的时候还挺有效的。
第二种方法就是像上面的方法一样,从最大值到第k大的值一一比较,肯定很麻烦。不如建堆来的快。但是做上面题目是比较适合的。