1. 程式人生 > 實用技巧 >2.13 子陣列的最大乘積

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;
	}
}