描述
给定一个数组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];)
对于A长度为1的情况,B无意义,故而无法构建,因此该情况不会存在。
示例1
输入:
[1,2,3,4,5]
复制
返回值:
[120,60,40,30,24]
复制
解题思路
算法公式:B[i]=A[0]A[1]...A[i-1]*A[i+1]...*A[n-1]
暴力法
如果使用暴力方法解题算法复杂度会达到O( ),空间复杂度为O(n)
```java public int[] multiply(int[] A) { int[] result = new int[A.length]; for (int i = 0 ;i < result.length ; i++){ result[i] = 1; for (int j = 0 ; j < A.length ; j++ ){ // 由题可以排除 i等于j if (i == j){ continue; } result[i] *=A[j]; } } return result; } ```
优化方法
思路:因为题目限制了不能使用除法,所以我们不能够先计算出从A[1]到A[n-1]整个的乘积再除以A[i],那么可以换种思路B[i]=A[0]A[1]...A[i-1]*A[i+1]...*A[n-1]
如果让C[i] = A[0]A[1]...A[i-1],D[i] = A[i+1]...A[n-1] 那么B[i] = C[i] * D[i] 即如下图
从黄色部门把每个B[i]划分为两个部分,分别计算出每个部分的值,这样的话只需要O(n)级别的算法复杂度既可以得出结果,并且空间复杂度为O(n)
``` public int[] multiply(int[] A) { int[] result = new int[A.length]; int item = 1; for (int i = 0 ; i < A.length ; i++){ //计算出C[i] 即 C[i] = A[0]*A[1]...A[i-1] result[i] = item; item *= A[i]; } item = 1; for (int i = A.length-1 ; i >=0 ; i--){ //item 即为 D[i] 即 D[i] = A[i+1]*A[i+2]...A[n-1] ,所以 result[i] *= item,即为B[i] result[i] *= item; item*=A[i]; } return result; } ```