一、题目描述
题目描述
给定一个数组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]。
可以看到B[i]是从A[0]连乘到A[i-1]==跳过A[i]==再由A[i-1]连乘到A[n]
如果没有题目限制的不能使用除法,那我计算一个全部的连乘再依次除以A[i]不就很爽(但他偏偏就限制了),所以接下来的问题是怎么绕过这个限制呢
思路的心路历程:
每次都计算一遍是不可能的,这辈子也不可能的,想都不要想。所以肯定要利用已经计算好的乘积,但是怎么排除A[i],我一开始的想法是使用一个很大的存储结构,存储每一个从A[a]连乘到A[b] (a<b) 的乘积,但是我也知道这样不现实。
于是就是这个改进版:
先算前一半,从B[1]开始每一个B[i]都是B[i-1]*A[i-1](如上图)
后一半就是将它反过来,但这个时候不能再直接用B[i]去存了,需要一个temp
三、代码
class Solution {
public:
vector<int> multiply(const vector<int>& A) {
int len=A.size();
vector<int>B(len);
if(len<=1)
return B;
B[0]=1;
for(int i=1;i<len;i++)
{
B[i] = B[i-1]*A[i-1];
}
int temp=1;
for(int i=len-2;i>=0;i--)
{
temp*=A[i+1];
B[i]*=temp;
}
return B;
}
};
public class Solution {
public int[] multiply(int[] A) {
if(A.length <= 1)
return A;
int [] B = new int[A.length];
B[0] = 1;
for(int i = 1; i < A.length; i++){
B[i] = B[i-1] * A[i-1];
}
int temp = 1;
for(int j = A.length - 2; j >= 0; j--){
temp *= A[j+1];
B[j] *= temp;
}
return B;
}
}