最大的三个数的乘积

最大的三个数的乘积

内容描述:                                                       
给定一个无序数组,包含正数,负数和0,要求从中找出3个数的乘积,
使得乘积最大,要求时间复杂度:O(n),空间复杂度:O(1); 
输入描述:
       无序整数数组A[n]
输出描述:
       满足条件的最大乘积
示例1
输入
3 4 1 2
输出
24
这里需要注意一下的是,题目中的输入格式是 输入数组长度 4 输入数组的每个元素 3 4 1 2 输出 24 问题的之外的一些注意点: 如果给定数组的长度小于3的话,那结果返回是0,还是提示不符合要求。 假设: 所给的数组的长度大于等于3,对于这种情况下,求3个数的最大乘积数。 思路分析: 1.基于暴力枚举的方法:最开始想到的是暴力的方法,3层循环,每一层 获取一个数组的元素,与当前的最大值进行比较,由于有时间复杂度要求, 明显是不可以的。 // 不过这个可以用来对下面方法的结果进行测试。 public long muliptyMax(double[] a) { long sum=a[0]*a[1]*a[2]; for(int i=0;i<a.length;i++) { for(int j=i+1;j<a.length;j++) { for(int k=j+1;k<a.length;k++) { if(sum<a[i]*a[j]*a[k]) sum=a[i]*a[j]*a[k]; } } } return sum; } 2.对结果进行分析,要求三个数的最大乘积可能形式有: 1.无序数组都是正数(包含0),找三个最大的数。 2.无序数组都是负数,仍然是找三个最大的数。 3.有正数(包括0)有负数。可能的形式就是三个正数或者是两负一正。 通过这些结果会发现,只要我们可以保存这几个遍历数组时,可以把对应的 最大的三个正数,二个最小的负数找到,就可以求出三个数的最大乘积了。 细分问题:遍历一次数组怎么实现得到得到最大的三个数和最小的两个数。 从最小的两个数进行分析:我们可以定义两个变量来保存最小负数和次小 负数,遍历数组中的元素时,和当前的这两个变量进行比较。 1.如果当前元素比最小负数小,把最小负数的值赋给次小负数,把当前元素 赋给最小负数。比如:当前元素是-5 ,最小负数是 -4 ,次小负数是 -3 那么比较后就最小负数是 -5 ,次小负数是 -4 2.如果当前元素比最小负数大,但是次小元素小,就当前元素赋给次小元素。 比如:当前元素是-5 ,最小负数是 -6 ,次小负数是 -3 那么比较之后的结果就是 最小负数是 -6 ,次小负数是 -5 注意:基于对两个最小负数的求法,对于两个变量的初始值,就很重要了。 1.一般是使用数组中的元素作为初始值。比如a[0] 但是这样是有问题的(可以解决,相对麻烦,要赋值之前要进行判断) ),使用不在数组范围中的值进行初始化。 使用Integer.MIN_VALUE;Integer.MAX_VALUE赋值。 其实我们不一定要赋值,可以使用下标。 因为下标是唯一的,元素中的数据值可能是重复的。 还有要注意的一点保存数据的范围,用long保存数据,否则会溢出。 二个最小的负数找到,同理可以找到三个最大的整数了。
import java.util.Scanner;
public class ThreeDataMulipty {
    public static int muliptyMax(int[] a)  { 
        // 定义三个变量保存最大的三个数。
        int maxOne=Integer.MIN_VALUE;
        int maxTwo=Integer.MIN_VALUE;
        int maxThree=Integer.MIN_VALUE;
        // 两个最小负数
        int minOne=Integer.MAX_VALUE;
        int minTwo=Integer.MAX_VALUE;
//        System.out.println("每次=maxone:"+maxOne+"maxtwo:"+maxTwo+"maxthree:"+maxThree);
        // 遍历一次数组,将各个合适的元素放到对应的位置。
        for(int i=0;i<a.length;i++)  
        {
          if(maxOne<a[i])  {
             maxThree=maxTwo;
             maxTwo=maxOne;
             maxOne=a[i];
          } else {
             if(maxTwo<a[i])  {
                maxThree=maxTwo;
                maxTwo=a[i];
             } else  {
                if (maxThree<a[i]) {
                  maxThree=a[i];
                }
             }
          }
//          System.out.println("每次=maxone:"+maxOne+"maxtwo:"+maxTwo+"maxthree:"+maxThree);
          // 求两个最小负数。
          if(minOne>a[i])  {
             minTwo=minOne;
             minOne=a[i];
          } else  {
             if(minTwo>a[i]) {
                minTwo=a[i];
             }
          }
         
        }
//        System.out.println(Arrays.toString(a));
//        System.out.println("maxone:"+maxOne+"maxtwo:"+maxTwo+"maxthree:"+maxThree);
//        System.out.println("minone:"+minOne+"mintwo:"+minTwo);
        int maxMulipty=maxOne*maxTwo*maxThree;
        int minMulipty=minOne*minTwo*maxOne;
        return maxMulipty>minMulipty?maxMulipty:minMulipty;
    }
    public static void main(String[] args) {
        Scanner scn=new Scanner(System.in);
// 输入数组长度
int n=scn.nextInt(); int[] a=new int[n];
// 输入数组的每个元素
for(int i=0;i<n;i++) { a[i]=scn.nextInt(); } System.out.println(muliptyMax(a)); } }

 

 

转载于:https://www.cnblogs.com/lixiaochi/p/10694935.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值