题目描述
给定一个数组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]。不能使用除法。
解法:
方法1:暴力解法。
1)假设A=[1,2,3],那么B[0] = A[1]*A[2] B[1] = A[0]*A[2] B[2] = A[0]*A[1]
2)可以发现规律,B[i]就等于A的连乘,除掉A[i]那个数
3)两个嵌套循环,很容易就写出来,复杂度为O(N^2),内层循环用个continue去掉相等的情况就可以了
class Solution {
public:
vector<int> multiply(const vector<int>& A) {
int len = A.size();
if(len == 0) return A;
vector<int> B(len, 1);
/暴力破解法
for(int i = 0; i < len; i++) {
int temp = 1;
for(int j = 0; j < len; j++) {
if(i == j) continue;
temp *= A[j];
}
B[i] = temp;
}
return B;
}
};
方法2:优雅的解法
1)令C[i] = A[0]*A[1]*...*A[i-1],那么我们可以得到,C[i] = C[i-1] * A[i-1],因为C[i-1] = A[0]*A[1]*...*A[i-3]*A[]i-2]
2)令D[i] = A[i+1]*...*A[n-1],那么我们可以得到,D[i] = D[i+1]*A[i+1],因为D[i+1] = A[i+2]*...*A[n-1]
3 ) B[i] = C[i]*D[i]
4 ) 这需要确定1)和2)中循环计算C和D时候的循环条件,1)中,最小为i-1,所以,i必须从1开始,且小于数组长度len,取不到;同理2)中,最大为i+1,因此只能i小于len-2,否则数组将越界,最小i可以取到0下标。
class Solution {
public:
vector<int> multiply(const vector<int>& A) {
int len = A.size();
if(len == 0) return A;
vector<int> B(len, 1);
///优美的解法
vector<int> front(len, 1);
vector<int> back(len, 1);
vector<int> B(len, 1);
for(int i = 1; i < len; i++) {
front[i] = front[i-1] * A[i-1];
}
for(int i = len - 2; i >= 0; i--) {
back[i] = back[i+1] * A[i+1];
}
for(int i = 0; i < len; i++) {
B[i] = front[i] * back[i];
}
return B;
}
};