2.13 子数组的最大乘积
2.13 子数组的最大乘积
基本问题:给定一个长度为N的整数数组,只允许用乘法,不允许用除法,计算任意(N-1)个数组的组合乘积中最大的一组,并写出算法的时间复杂度
解法:
- 解法1:直接暴力
时间复杂度\(O(n^2)\),空间复杂度\(O(1)\) - 解法2:用空间换时间
时间复杂度\(O(n)\),空间复杂度\(O(n)\)
s[i]表示数组前i个元素的乘积
t[i]标记数组后N-i和元素的乘积
p[i]表示不包括第i个元素的乘积 - 解法3:利用全部元素的乘积的结果来进行分步判断
时间复杂度\(O(n)\),空间复杂度\(O(1)\)
all coding
// 2.13 子数组的最大乘积
import java.util.*;
class Test{
public static void main(String[] args) {
/**
基本问题:给定一个长度为N的整数数组,只允许用乘法,不允许用除法,计算任意(N-1)个数组的组合乘积中最大的一组,并写出算法的时间复杂度
解法:
解法1:直接暴力
时间复杂度$O(n^2)$,空间复杂度$O(1)$
解法2:用空间换时间
时间复杂度$O(n)$,空间复杂度$O(n)$
s[i]表示数组前i个元素的乘积
t[i]标记数组后N-i和元素的乘积
p[i]表示不包括第i个元素的乘积
解法3:利用全部元素的乘积的结果来进行分步判断
时间复杂度$O(n)$,空间复杂度$O(1)$
*/
int[] arr = new int[]{5,2,3,4,5};
print(arr);
System.out.print(calcMulti1(arr));
System.out.println();
System.out.print(calcMulti2(arr));
System.out.println();
System.out.print(calcMulti3(arr));
System.out.println();
System.out.print(Integer.MIN_VALUE);
}
public static void print(int[] arr){
for(int i:arr) System.out.print(i + " ");
System.out.println();
}
/**
解法1 : 直接暴力求解
*/
public static int calcMulti1(int[] arr){
int max = Integer.MIN_VALUE;
for(int i = 0;i<arr.length;i++){
int tmp = 1;
for(int j = 0;j<arr.length;j++){
if(j == i) continue;
tmp*=arr[j];
}
max = Math.max(max,tmp);
}
return max;
}
/**
解法2 :
*/
public static int calcMulti2(int[] arr){
//
int[] s = new int[arr.length + 1];
s[0] = 1;
//
int [] t = new int[arr.length + 1];
t[arr.length] = 1;
for(int i = 0;i<arr.length;i++) s[i+1] = s[i] * arr[i];
for(int i = arr.length -1;i>=0;i--) t[i] = t[i+1] * arr[i];
int[] p = new int[arr.length];
for(int i = 0;i<arr.length;i++) p[i] = s[i] * t[i+1];
int max = Integer.MIN_VALUE;
for(int i:p) max = Math.max(max,i);
return max;
}
/**
解法3:
*/
public static int calcMulti3(int[] arr){
int mutiSum = 1;
// 计算所有元素的乘积
for(int i:arr) mutiSum*=i;
// 所有元素的乘积==0
if(mutiSum == 0){
// 计算删除一个0之后的乘积
int mutiSum2 = 1;
boolean flag = false;
for(int i :arr){
if(i == 0 && !flag){
flag = true;
continue;
}
mutiSum2*=i;
}
// 如果还有第二个0
if(mutiSum2 == 0) return 0;
// 将0剔除之后的n-1个元素的乘积大于0,删除一个最小的正数
if(mutiSum2 > 0) {
int min = Integer.MAX_VALUE;
for(int i:arr) if(i>0) min = Math.min(min,i);
return mutiSum2/min;
}
// 将0剔除之后的n-1个元素的乘积小于0,删除一个最大的负数
if(mutiSum2 < 0){
int max = Integer.MIN_VALUE;
for(int i:arr) if(i<0) max = Math.max(max,i);
return mutiSum2/max;
}
// 所有元素的乘积 < 0
}else if(mutiSum <0){
int max = Integer.MIN_VALUE;
// ,删除一个最大的负数
for(int i:arr) if(i<0) max = Math.max(max,i);
return mutiSum/max;
// 所有元素的乘积 > 0
}else{
int min = Integer.MAX_VALUE;
// ,删除一个最小的正数
for(int i:arr) if(i>0) min = Math.min(min,i);
return mutiSum/min;
}
return 0;
}
}
Saying Less Doing More