2.13 子陣列的最大乘積
阿新 • • 發佈:2020-11-24
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; } }