三个数的最大乘积
描述
给定一个无序数组,包含正数、负数和0,要求从中找出3个数的乘积,使得乘积最大,要求时间复杂度:O(n),空间复杂度:O(1)。
解题
Solution1
/**
* 求数组中三个数的最大乘积
* 因为数组中有正负数,所以最大乘积为,三个最大值的乘积与两个最小值和最大值的乘积中的较大值
* 快速排序
*/
public class Solution {
public long solve (int[] A){
if(A.length==3) return A[0]*A[1]*A[2];
int n=A.length-1;
quickSort(A,0,n);//快速排序
int min1=A[0],min2=A[1];
int max1=A[n],max2=A[n-1],max3=A[n-2];
return Math.max((long)min1*min2*max1,(long)max1*max2*max3);//转换长整型再求最大值
}
public void quickSort(int[] arr,int low,int height){
if (low<height){
int point=partition(arr,low,height);//定点
quickSort(arr,low,point-1);//递归左边
quickSort(arr,point+1,height);//递归右边
}
}
public int partition(int[] arr,int low,int height){
int first=arr[low];//标志点
while (low<height){
while (low<height&&arr[height]>=first) height--;//右边遍历
swap(arr,low,height);//交换
while (low<height&&arr[low]<=first) low++;//左边遍历
swap(arr,low,height);
}
return low;
}
private void swap(int[] arr,int left,int right){
int temp=arr[left];
arr[left]=arr[right];
arr[right]=temp;
}
}
Solution2
/**
* 求数组中三个数的最大乘积
* 因为数组中有正负数,所以最大乘积为,三个最大值的乘积与两个最小值和最大值的乘积中的较大值
* 快速排序
*/
public class Solution2 {
public long solve (int[] A){
if(A.length==3) return A[0]*A[1]*A[2];
int n=A.length-1;
quickSort(A,0,n);
int min1=A[0],min2=A[1];
int max1=A[n],max2=A[n-1],max3=A[n-2];
return Math.max((long)min1*min2*max1,(long)max1*max2*max3);
}
private void quickSort(int[] A, int low, int high) {
if (low>=high) return;//终止运算
int cur=A[low];//标志点
int i=low,j=high;
while (low<high){
while (low<high&&A[high]>=cur) high--;//右遍历
while (low<high&&A[low]<=cur) low++;//左遍历
if (low<high){
int temp =A[low];
A[low]=A[high];
A[high]=temp;
}
}
A[i]=A[low];//交换
A[low]=cur;
quickSort(A,i,low-1);//递归
quickSort(A,low+1,j);
}
}
Solution3
/**
* 求数组中三个数的最大乘积
* 因为数组中有正负数,所以最大乘积为,三个最大值的乘积与两个最小值和最大值的乘积中的较大值
* 查找算法
*/
public class Solution3 {
public long solve (int[] A){
int min1=Integer.MAX_VALUE,min2=Integer.MAX_VALUE;
int max1=Integer.MIN_VALUE,max2=Integer.MIN_VALUE,max3=Integer.MIN_VALUE;
for (int i = 0; i < A.length; 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 Math.max((long)max1*max2*max3,(long)min1*min2*max1);
}
}