描述
给定一个长度为 nn 的无序数组 AA ,包含正数、负数和 0 ,请从中找出 3 个数,使得乘积最大,返回这个乘积。
要求时间复杂度: O(n)O(n) ,空间复杂度: O(1)O(1) 。
数据范围:
3 \le n \le 10^43≤n≤104
-10^4 \le A[i] \le 10^4−104≤A[i]≤104
示例1
输入:
[3,4,1,2]
复制返回值:
24
复制
解题思路:
解题思路:遍历数组,找到最大的三个数和最小的两个数,三个数的最大乘积来源可能有两种,一种是三个最大的数相乘,另一种是两个最小的数和一个最大的数相乘。
Java题解,使用BigInteger,强行算出来比较大小。
只有两种可能 要不就是三正 要不就是两负一正。
先按照从大到小的顺序排序,选择前三位和后两位数据,对后两位数进行判断即可。
只有两种可能:三个正;两个负加一个正;所以排序之后相乘再比较就好。
数组中最大值为0的话结果就是0,全为负数则取所有最大值相乘,有正有负则要分情况讨论。
要想找到最大乘积,对这个数组进行排序,如果最后一个数为正数,这个数组有可能存在负数,如果全为正数,则最大的三个数乘积就是排好序的最后三个相乘,如果存在负数,则一定是第一个数,第二个数,最后一个数相乘后与最后三个数相乘比较大小,如果最后一个数为负数,则最大的三个数乘积为排好序的最后三个数相乘。
先将数组进行排序,这里是升序排序;然后分析:
1.全是正数或者全是负数,毋庸置疑,最大乘积就是选最大的三个数:result0 = A[A.length -1]*A[A.length -2]*A[A.length -3]
1.包含正数和负数,最大乘积就是要么选择最小的两个负数加最后一个最大的正数:result1 = A[A.length -1]*A[0]*A[1]
若前面只有一个负数,最大乘积还是选最大的三个数:result0 = A[A.length -1]*A[A.length -2]*A[A.length -3]
因此最大三个数的乘积就是 result= result0 > result1 ? result0 : result1。
本来以为只要排序取最大的前三位乘积的,脑子瓦特了,没想到还有可能是负负得正,最小的两位乘上最大的。
*****************************************************************************************
long
long
min1=
10001
,min2=
10001
;
long
long
max1= -
10001
,max2=-
10001
,max3=-
10001
;
for
(
int
i=
0
;i<ALen;i++)
{
if
(A[i]<min1)
{
min2=min1;
min1=A[i];
}
else
if
(A[i] < min2)
{
min2=A[i];
}
if
(A[i]>max1)
{
max3=max2;
max2=max1;
max1=A[i];
}
else
if
(A[i] > max2)
{
max3=max2;
max2=A[i];
}
else
if
(A[i] > max3)
{
max3=A[i];
}
}
return
(max1*max2*max3) > (min1*min2*max1) ? max1*max2*max3 : min1*min2*max1 ;