第2章 数字之魅——子数组的最大乘积

子数组的最大乘积

问题描述

  给定一个长度为N的整数数组,只允许用乘法,不能用除法,计算任意(N-1)个数的组合乘积中最大的一组,并写出算法的时间复杂度。

  我们把所有可能的(N-1)个数的组合找出来,分别计算它们的乘积,并比较大小。由于总共有N个(N-1)个数的组合,总的时间复杂度为O(N2),但显然这不是最好的解法。

分析与解法

【解法一】时间复杂度为O(N)

具体代码如下:

 1 package chapter2shuzizhimei.maxmutiply;
 2 /**
 3  * 子数组的最大乘积
 4  * 【解法一】
 5  * @author DELL
 6  *
 7  */
 8 public class MaxMutiply1 {
 9     //寻找乘积的最大值
10     public static long findMax(long a[]){
11         int n = a.length,i;
12         long[] s = new long[n]; //s[i]为第i个之前元素的乘积
13         s[0] = 1;
14         long[] t = new long[n]; //t[i]为第i个之后元素的乘积
15         t[n-1] = 1;
16         long[] p = new long[n]; //p[i]为数组除第i个元素外,其他N-1个元素的乘积
17         for(i=1;i<n;i++){
18             s[i]=s[i-1]*a[i-1];
19         }
20         for(i=n-2;i>=0;i--){
21             t[i]=t[i+1]*a[i+1];
22         }
23         long max = s[0]*t[0];
24         for(i=0;i<n;i++){
25             p[i] = s[i]*t[i];
26             if(p[i]>max)
27                 max = p[i];
28         }
29         return max;
30     }
31     public static void main(String[] args) {
32         long a[] = {1,-2,3,5};
33         System.out.println("最大乘积为:"+findMax(a));
34 
35     }
36 
37 }

程序运行结果如下:

最大乘积为:15

【解法二】

为了避免溢出,不直接求乘积,而是返回要剔除的那个数组元素,代码如下:

 1 package chapter2shuzizhimei.maxmutiply;
 2 
 3 /**
 4  * 子数组的最大乘积
 5  * 【解法二】
 6  * @author DELL
 7  *
 8  */
 9 public class MaxMutiply2 {
10     //寻找乘积最大时应该剔除的元素
11     public static void findMax(long a[]){
12         int negative = 0; //存放负数个数
13         int zero = 0;  //存放零个数
14         long minPositive = 0; //最小正数
15         long minNegative = 0;  //绝对值最小负数,即最大的负数
16         int n = a.length,i;
17         for(i=0;i<n;i++){
18             if(a[i]>0){
19                 if(minPositive==0)
20                     minPositive=a[i];
21                 else if(a[i]<minPositive)
22                     minPositive=a[i];
23             }
24             else if(a[i]==0){
25                 zero++;
26             }
27             else{
28                 negative++;
29                 if(minNegative==0)
30                     minNegative=a[i];
31                 else if(a[i]>minNegative)
32                     minNegative=a[i];
33             }
34         }
35         if(zero>=2){
36             System.out.println("任意去掉一个元素就行,最大乘积为0!");
37             return;
38         }
39         if(zero==1){
40             if(negative%2==0){
41                 System.out.println("乘积最大时应该剔除的元素为:0");
42                 return;
43             }
44             else{
45                 System.out.println("任意去掉一个非0元素就行,最大乘积为0!");
46                 return;
47             }
48         }
49         if(negative%2!=0){
50             System.out.println("乘积最大时应该剔除的元素为:"+minNegative);
51             return;
52         }
53         else{
54             System.out.println("乘积最大时应该剔除的元素为:"+minPositive);
55             return;
56         }
57     }
58     public static void main(String[] args) {
59         long a[] = {1,-2,3,5,0,-1};
60         findMax(a);
61 
62     }
63 
64 }

程序运行结果如下:

乘积最大时应该剔除的元素为:0
原文地址:https://www.cnblogs.com/gaopeng527/p/4626354.html