题目
描述
- 给定一个无序数组,包含正数、负数和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个变量,所以为常数级空间复杂度。

京公网安备 11010502036488号