给定一个数组 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],每一次计算都要将A中除第 i 个元素外的所有元素相乘,则总的时间复杂度为O(n^2),这种解法不是最好的。
构建矩阵解法
我们将B[i]=A[0] x A[1] x ... x A[i-1] x A[i+1] x A[i+2] x... xA[n-1]拆分成两部分A[0] x A[1] x ... x A[i-1]和A[i+1] x A[i+2] x... xA[n-1]的乘积。因此,数组B可以用矩阵表示:- 构建前向乘积数组C[i]=A[0] x A[1] x … x A[i-1],即C[i]=C[i-1] x A[i-1];
- 构建后向乘积数组D[i]=A[n-1] x A[n-2] x … x A[i+1],即D[i]=D[i+1] x A[i+1];
通过C[i],D[i]来求B[i]:B[i]=C[i] x D[i]
时间复杂度:O(n)
public static int[] multiply(int[] data) {
if (data == null || data.length < 2) {
return null;
}
int[] result = new int[data.length];
// result[0]取1
result[0] = 1;
for (int i = 1; i < data.length; i++) {
// 第一步每个result[i]都等于于data[0]*data[1]...data[i-1]
// 当i=n-1时,此时result[n-1]的结果已经计算出来了
result[i] = result[i -1] * data[i - 1];
}
// tmp保存data[n-1]*data[n-2]...data[i+1]的结果
int tmp = 1;
// 第二步求data[n-1]*data[n-2]...data[i+1]
//result[n-1]的结果已经计算出来,所以从data.length-2开始操作
for (int i = data.length - 2; i >= 0; i--) {
tmp *= data[i + 1];
result[i] *= tmp;
}
return result;
}