题目描述:给定一个数组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]。不能使用除法。
【分析】
一、连乘n-1个数字得到B[i]。O(n*n)
class Solution {
public:
vector<int> multiply(const vector<int>& A) {
vector<int> result;
int len=A.size();
if(len<=0)//鲁棒性
return result;
for(int j=0;j<A.size();j++)//B中元素,数目和A一样
//两个数组A和B,A中所有元素(除和B下标相同的位置)做乘积得到B对应下标元素
{
int temp=1;//临时存储每一次乘积的结果
for(int i=0;i<A.size();i++)//对A中元素遍历
{
if(i==j)//下标和B相同的不做乘法计算,直接跳过
{
continue;
}
temp*=A[i];//依次累乘积
}
result.push_back(temp);//每次值放入B中,下次开始又从1开始
}
return result;
}
};
二、把B[i]=A[0]*A[1]*.....*A[i-1]*A[i+1]*.....*A[n-1]。看成A[0]*A[1]*.....*A[i-1]和A[i+1]*.....A[n-2]*A[n-1]两部分的乘积。
设定C[i]=A[0]*A[1]*...*A[i-1],D[i]=A[i+1]*...*A[n-2]*A[n-1]。C[i]可以用自上而下的顺序计算出来,即C[i]=C[i-1]*A[i-1]。类似的,D[i]可以用自下而上的顺序计算出来,即D[i]=D[i+1]*A[i+1]。
第一个for循环用来计算上图1范围的数,第二个for循环用来计算上图2范围的数。
class Solution {
public:
vector<int> multiply(const vector<int>& A) {
int len=A.size();
vector<int> B(len);
if(len<=0)//鲁棒性
return B;
B[0]=1;
/*第一个for循环用来计算上图1范围(下标小于i)的数,第二个for循环用来计算上图2范围(下标大于i)的数*/
for(int i=1;i<len;i++)//把A元素从i处分为两部分
{
B[i]=B[i-1]*A[i-1];//C[i]=C[i-1]*A[i-1]
}
int temp = 1;
for(int i=len-2;i>=0;i--)
{
temp*= A[i+1];//D[i]=D[i+1]*A[i+1]
B[i]*=temp;
}
return B;
}
};