题目:
给定一个数组
A[0,1,...,n−1
],请构建一个数组
B[0,1,...,n−1]
。
其中
B
中的元素
直观思路:
计算每一个B[i],每一次计算都要将A中除第 i 个元素外的所有元素相乘,O(n),则总的时间复杂度为O(n^2);
O(n2)
一般都不是最优算法复杂度。
改进思路:
将计算过程画出来,寻找规律
如上图所示,每行跳过红色数字,黑色数字的乘积就是对应的B[i].那么以红色数字为分割线,左侧数组设为D,右侧设为C,则B= C*D;
则
D[0] = 1; D[i] = D[i-1] * A[i-1]; 从上到下计算
C[len-1] = 1; C[i-1] = C[i] * A[i]; 从下到上计算
最后的 B[i] = D[i]*C[i];
时间复杂度O(n),空间复杂度O(n)
#include <iostream>
using namespace std;
void ConstructAarry(int *A, int length, int* B) {
if (A == NULL || length <= 0)
return;
int* C = new int[length];
int* D = new int[length];
D[0] = 1; // 计算D
for (int i = 1; i < length; i++) {
D[i] = D[i-1] * A[i-1];
}
C[length-1] = 1; // 计算C
for (int j = length-1; j > 0; j--) {
C[j-1] = C[j] * A[j];
}
// 计算B
for (int i = 0; i < length; i++) {
B[i] = D[i]*C[i];
}
delete []C;
delete []D;
}
int main() {
int A[] = {1,2,3,4,5};
int len = sizeof(A)/sizeof(A[0]);
int* B = new int [len];
ConstructAarry(A, len, B);
for (int i = 0; i < len; i++)
cout << B[i] << " ";
}
结果:
120 60 40 30 24 [Finished in 0.6s]