一个长度为N的数组,求哪N-1个数组成的乘积最大

package suanfa.impover;

import java.util.Arrays;
import java.util.Scanner;

/**
 * 一个长度为N的数组,求哪N-1个数组成的乘积最大
 */
public class MaxSubArrayMultiplication {

    //  方法一:得到乘积,依次去除。处理的数据中不能含0
    //  当有0,负数混杂时,该方法太局限(1个0,一个负数等等情况)
    public static void divisorConcrete(int [] a){
        int product=1;
        for (int i=0;i<a.length;i++){
            product *= a[i];
        }

        int max,maxIndex;
        max=product/a[0];
        maxIndex=0;

        for (int i=1;i<a.length;i++){
            if (product/a[i]>max){
                max=product/a[i];
                maxIndex=i;
            }
        }

        System.out.println("It should take out:"+a[maxIndex]);
        System.out.println("Max value is: "+max);
    }


    //  方法二:借用数组,可以处理含0的数据
    public static void useArrayConcrete(int []a){
        //  left[i]:第i为之前的数的乘积,right[i]:第i为之后的数的乘积,product[i]:出去第i为剩余数的乘积
        int [] left,right,product;
        left=new int[a.length+1];
        right=new int[a.length+2];
        product=new int[a.length+1];
        left[0]=left[a.length]=right[0]=right[a.length+1]=1;
        for (int i=1;i<=a.length;i++){
            left[i] = a[i-1]*left[i-1];
        }
        for (int i=a.length;i>0;i--){
            right[i] =a[i-1]* right[i+1];
        }

        //  除去第i位剩下数的乘积
        for (int i=1;i<=a.length;i++){
            product[i]=left[i-1]*right[i+1];
        }
        int max=product[1];
        int maxIndex=0;
        for (int i=2;i<=a.length;i++){
            if (product[i]>=max){
                max=product[i];
                maxIndex=i-1;
            }
        }

        System.out.println("It should take out: "+a[maxIndex]);
        System.out.println("Max value is: "+max);
    }

    /**
     *  以上的两种方法,除过本身存在的局限性外,当数据量过大时,在相乘时,会产生溢出
     *
     *  不需要借助辅助数组,时间复杂度为O(N),且不会产生溢出的算法!
     */

    public static void countConcrete(int [] a) {
        int times0,index0,timesNegative,indexMaxNegative,indexMinPositive;
        times0=timesNegative=0;
        index0=indexMaxNegative=indexMinPositive=-1;
        int minPositive,maxNegative;
        minPositive=Integer.MAX_VALUE;
        maxNegative=Integer.MIN_VALUE;

        //  计算0,正数,负数出现的次数
        for (int i=0;i<a.length;i++){
            if (a[i]==0){
                times0++;
                index0=i;
            }else {
                if (a[i]>0){
                    if(a[i]<minPositive){
                        minPositive=a[i];
                        indexMinPositive=i;
                    }
                }else {
                    if (a[i]>maxNegative){
                        maxNegative=a[i];
                        indexMaxNegative=i;
                    }
                    timesNegative++;
                }
            }
        }
        //  确定要出去数的索引与最大乘积
        int ridIndex,maxProduct;
        if (times0>1){
            ridIndex=index0;
            maxProduct=0;
        }else {
            //  有一个0的情况
            if (times0==1){
                if ( (timesNegative&0x01)==1){
                    ridIndex=indexMaxNegative;
                }else {
                    ridIndex=index0;
                }
            }else {
                if ( (timesNegative&0x01)==1){
                    ridIndex=indexMaxNegative;
                }else {
                    ridIndex=indexMinPositive;
                }
            }
            maxProduct=getProduct(a,ridIndex);
        }
        System.out.println("max product is:"+maxProduct);
        System.out.println("take off index is :"+ridIndex);
    }
    private static int getProduct(int [] a,int index){
        int sum=1;
        for(int i=0;i<a.length;i++){
            if (i!=index){
                sum *= a[i];
            }
        }

        return sum;
    }
}
/*
5
1 2 3 4 5

 */

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值