题目:给定一个数组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[i]都通过遍历所有元素进行乘积运算,那么总的时间复杂度显然是O(n^2),由于计算B[i]时存在大量重复的操作,因此思路是通过递推关系保留每一步的计算结果从而利用已经计算出来的结果减少时间复杂度。整个乘积、求和过程可以看作图中所示的矩阵。
图中每一行都是A[1]---A[n-1],用1表示不用乘的A[i],因此只要将每一行相乘得到B[i],然后将B[i]数组相加即可得到结果。每一项B[i]可以分成两个部分,左边部分C[i]和右边部分D[i],B[i]=C[i]*D[i],可以建立两个数组C,用来记录每一项C[i], C[0]=1;C[i]=C[i-1]*A[i-1];用数组D记录每一项D[i],D[n-1]=1;D[n-1-i]=D[n-i]*A[n-i],i从1开始。即通过使用两个额外的数组空间来完成乘积求和,时间复杂度为O(n);
//给定一个数组,计算乘积之和,图形化为矩阵以便于理解
import java.util.ArrayList;
public class Solution {
public int[] multiply(int[] A) {
//特殊的输入
if(A==null||A.length<=0) return null;
//构造两个额外的数组C,D来记录部分乘积
int C[]=new int[A.length];
int D[]=new int[A.length];
//初始化上下三角第一个元素为1
C[0]=1;
D[A.length-1]=1;
//这里n就是数组的长度
int n=A.length;
//遍历整个数组,完成C.D数组的记录,注意i从1开始
for(int i=1;i<A.length;i++){
C[i]=C[i-1]*A[i-1];
D[n-1-i]=D[n-i]*A[n-i];
}
int B[]=new int[A.length];
for(int i=0;i<A.length;i++){
B[i]=C[i]*D[i];
}
return B;
}
}