题目

描述

  • 给定一个无序数组,包含正数、负数和0,要求从中找出3个数的乘积,使得乘积最大,要求时间复杂度:,空间复杂度:

方法一

思路

求一个数组中的三数最大乘积,且包括负数,所以需要考虑两种情况:

  • 两个最小负数,一个最大正数
  • 三个最大正数
    所以只需要对其进行升序排序,取这两种情况中最大值即可。

具体步骤

  • 通过JDK自带的Array.sort对数组进行升序排序;
  • 计算两种情况各自的乘积
  • 代码如下:
    import java.util.*;
    public class Solution {
    /**
    * 最大乘积
    * @param A int整型一维数组 
    * @return long长整型
    */
    public long solve (int[] A) {
       // 升序排序
       Arrays.sort(A);
       return Math.max((long)A[0]*A[1]*A[A.length-1],
                       (long) A[A.length-1] * A[A.length-2] * A[A.length-3]);
    }
    }
  • 时间复杂度:,JDK的Array.sort函数的时间复杂度为
  • 空间复杂度:,常数级空间复杂度。

方法二

思路

方法一的时间复杂度为,但是题目要求的是,显然方法一是无法满足要求的,而排序的时间复杂度基本上都在以上,当然使用线性的排序方法也可以;不过这里考虑到题目只是要求找出前三大以及前二小的数值,所以可以遍历一遍数组,将这几个数直接找出来。

具体步骤

  • 见下图例子
    图片说明
    图片说明
  • 代码如下:
import java.util.*;
public class Solution {
/**
* 最大乘积
* @param A int整型一维数组 
* @return long长整型
*/
public long solve (int[] A) {
   // 最大的第二大的和第三大的
   int[] maxNums = new int[]{Integer.MIN_VALUE,Integer.MIN_VALUE,Integer.MIN_VALUE};
   //最小的和第二小的(负数的时候要用)
   int[] minNums = new int[]{Integer.MAX_VALUE,Integer.MAX_VALUE};
   for(int i = 0;i < A.length;i ++){
       if(A[i] < minNums[0]){//更新最小值
           minNums[1] = minNums[0];
           minNums[0] = A[i];
       }else if(A[i] < minNums[1]){//更新第二小
           minNums[1] = A[i];
       }
       if (A[i] > maxNums[0]){//更新最大值
           maxNums[2] = maxNums[1];
           maxNums[1] = maxNums[0];
           maxNums[0] = A[i];
       }else if(A[i] > maxNums[1]){//更新第二大
           maxNums[2] = maxNums[1];
           maxNums[1] = A[i];
       }else if(A[i] > maxNums[2]){//更新第三大
           maxNums[2] = A[i];
       }
   }
   long a = (long)minNums[0] * minNums[1] * maxNums[0];
   long b = (long)maxNums[0] * maxNums[1] * maxNums[2];
   return Math.max(a,b);
}
}
  • 时间复杂度:,遍历一遍数组,n;
  • 空间复杂度:,只是使用了5个变量,所以为常数级空间复杂度。