剑指offer之构建乘积数组C++解法
给定一个数组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]。不能使用除法。
B0 | 1 | A1 | A2 | … | An-2 | An-1 |
---|---|---|---|---|---|---|
B1 | A0 | 1 | A2 | … | An-2 | An-1 |
B2 | A0 | A1 | 1 | … | An-2 | An-1 |
… | A0 | A1 | … | 1 | An-2 | An-1 |
Bn-2 | A0 | A1 | … | An-3 | 1 | An-1 |
Bn-1 | A0 | A1 | … | An-3 | An-2 | 1 |
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-1]两部分的乘积,也就是上表中每行里‘1’的左边和右边的乘积。
把左边的乘积定义为B0[i]=A[0]×A[1]×…×A[i-1],i从1到n-1;右边的乘积定义为B1[i]=A[i+1]×…×A[n-1],i从0到n-2。
观察上表,可以看出B[i]之间的规律:对于B0[i],从上往下,有B0[i]=B0[i-1]×A[i-1];对于B1[i],从下往上,有B1[i]=B1[i+1]×A[i+1]。
因此,可以按照从上到下的顺序,即i从1到n-1,计算出每个B0[i]的结果,按照从下到上的顺序,即i从0到n-2,计算出每个B1[i]的结果。
然后B0[i]和B1[i]相乘可以得到B[i]。
class Solution {
public:
vector<int> multiply(const vector<int>& A) {
int n=A.size();
vector<int> B0(n,1);
vector<int> B1(n,1);
for(int i=1;i<n;i++){//从上往下一次计算 //for(int j=0;j<=i-1;j++) B0[i]*=A[j]; //连乘的方式
B0[i]=B0[i-1]*A[i-1];
}
for(int i=n-2;i>=0;i--)//从下向上依次计算
B1[i]=B1[i+1]*A[i+1];
vector<int> B(n,1);
for(int i=0;i<n;i++)
B[i]=B0[i]*B1[i];
return B;
}
};