題目描述
給定一個數組A[0,1,...,n-1],請構建一個數組B[0,1,...,n-1],其中B中的元素B[i]=A[0] A[1] ... A[i-1] A[i+1] ... A[n-1]。不能使用除法。(注意:規定B[0] = A[1] A[2] ... A[n-1],B[n-1] = A[0] A[1] ... A[n-2];)數組
解法一:暴力法
因爲 B[i]=A[0] A[1] ... A[i-1] A[i+1] ... A[n-1],乘積的結果不用將 A[i] 的值計算上就好了,暴力法用雙重循環就能解決,可是時間複雜度會很高,不推薦這種解法。ide
public int[] multiply(int[] A) { if (A == null || A.length == 0) { return null; } int[] res = new int[A.length]; for (int i = 0; i < A.length; i++) { res[i] = 1; for (int j = 0; j < A.length; j++) { if (i != j) { res[i] *= A[j]; } } } return res; }
解法二:動態規劃
根據上面這個圖,將 B[i] 的值分爲兩部分,再將這兩部分再乘積便可。以 i 爲界限(圖中灰色的部分),分爲左右兩部分。
以 B[2] 爲例:
左邊 B[2] = A[0] A[1];
右邊 B[2] = A[3] ... A[n-2] A[n-1];
最後的結果 = 左邊 B[2] 乘以 右邊 B[2]。
以 B[3] 爲例:
左邊 B[3] = A[0] A[1] A[2];
右邊 B[3] = A[4] ... A[n-2] A[n-1];
最後的結果 = 左邊 B[3] 乘以 右邊 B[3]。
以 B[4] 爲例:
左邊 B[4] = A[0] A[1] A[2] A[3];
右邊 B[4] = A[5] ... A[n-2] A[n-1];
最後的結果 = 左邊 B[4] 乘以 右邊 B[4]。
.
從以上來看,咱們會發現一些規律:
在 B[2] 的基礎上,咱們能夠將左邊的 B[3] 寫成這樣:左邊 B[3] = B[2] A[2];
在 B[4] 的基礎上,咱們能夠將右邊的 B[3] 寫成這樣:右邊 B[3] = A[4] B[4]。
代碼實現:
spa
public int[] multiply(int[] A) { if (A == null || A.length == 0) { return null; } //左邊部分 int[] left = new int[A.length]; left[0] = 1; for (int i = 1; i < A.length; i++) { left[i] = A[i - 1] * left[i - 1]; } //右邊部分 int[] right = new int[A.length]; right[A.length - 1] = 1; for (int i = A.length - 1; i > 0; i--) { right[i - 1] = right[i] * A[i]; } //計算總乘積,即將左右兩部分相乘 int[] res = new int[A.length]; for (int i = 0; i < A.length; i++) { res[i] = left[i] * right[i]; } return res; }