从数组中找出乘积最大的三个数

题目:

给定一个无序数组,包含正数、负数和0,要求从中找出3个数的乘积,使得乘积最大,要求时间复杂度:O(n),空间复杂度:O(1) 
输入描述:
无序整数数组A[n]

输出描述:
满足条件的最大乘积

输入例子1:
3 4 1 2

输出例子1:
24


思路:

由于空间复杂度和时间复杂度的要求,肯定无法先排序,因为排序最好时为O(n).整数的值任意需要分情况讨论

1.当数组的最大值<=0或者是数组的最小值>=0时,乘积最大就是数组中TOP3的乘积;

2.除第一种情况外,就需要考虑数组中的最大的3个数和最小的2个数,因为最大乘积肯定是在(2小+1大)或(3大)   中取得,因此比较两种记过就可得到最大乘积。

因此分析的,通过遍历数组有限次就可以实现该算法。最多需要遍历3次数组,额外空间最多为10个字节。满足算法要求


代码

public static void  pinduoduo()
	{
		Scanner sc=new Scanner(System.in);
		int N=sc.nextInt();
		long a[]=new long[N];
		for(int i=0;i<N;i++)
			a[i]=sc.nextInt();
		System.out.println(multiple(a));
	}
	public static long multiple(long a[])
	{
		int max_index=0;//最大对应的下标
		int min_index=0;//最小值对应的下标
		for(int i=1;i<a.length;i++)
		{
			if(a[min_index]>a[i])
				min_index=i;
			else if(a[max_index]<a[i])
				max_index=i;
		}
		
		long result=1;
		if(a[max_index]<=0||a[min_index]>=0)
		{
			result=result*a[max_index];
			long temp1=Long.MIN_VALUE;//数组的第二大值
			int index=-1;
			for(int i=0;i<a.length;i++)
			{
				if(i!=max_index&&a[i]>temp1)
					{
					temp1=a[i];
					index=i;
					}
			}
			result=result*temp1;
			temp1=Long.MIN_VALUE;//数组的第三大值
			int index2=-1;
			for(int i=0;i<a.length;i++)
			{
				if(i!=max_index&&i!=index&&a[i]>temp1)
					{
					temp1=a[i];
					index2=i;
					}
			}
			result=result*temp1;
			return result;
		}
		else if(a[max_index]>0&&a[min_index]<0)
		{
			long tempmin_2=Long.MAX_VALUE,index_min2=-1;//数组的第二小值对应的值和下标
			long tempmax_2=Long.MIN_VALUE,index_max2=-1;//数组的第二大值对应的值和下标
			long tempmax_3=Long.MIN_VALUE,index_max3=-1;//数组的第三大值对应的值和下标
			for(int i=0;i<a.length;i++)
			{
				if(i!=min_index&&a[i]<tempmin_2)
					{
					tempmin_2=a[i];
					index_min2=i;
					}
				if(i!=max_index&&a[i]>tempmax_2)
				{
					tempmax_2=a[i];
					index_max2=i;
				}
			}
			for(int i=0;i<a.length;i++)
			{
				if(i!=max_index&&i!=index_max2&&a[i]>tempmax_3)
				{
					tempmax_3=a[i];
					index_max3=i;
				}
			}
			long result1=a[min_index]*tempmin_2*a[max_index];
			long result2=a[max_index]*tempmax_2*tempmax_3;
			return result1>result2?result1:result2;
		}
		return 0;
	}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值