给定一个数组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];)
对于A长度为1的情况,B无意义,故而无法构建,因此该情况不会存在。
1、思路:因为B[i] = A[0]*A[1]*...*A[i-1]*A[i+1]*...*A[n-1],所以以i为分界线,可以将B[i]拆成A[0]*A[1]*...*A[i-1]和A[i+1]*A[i+2]*...*A[n-1]的乘积,令left[i] = A[0]*A[1]*...*A[i-1],right[i] = A[i+1]*A[i+2]*...*A[n-1],则
left[i+1] = left[i] * A[i]right[i] = A[i+1] * right[i+1]这样就可以先求出所有的left[i]和right[i],然后B[i]就等于left[i] * right[i]。
B[0]1A[1]A[2]A[3]......A[n-1]B[1]A[0]1A[2]A[3]......A[n-1]B[2]A[0]A[1]1A[3]......A[n-1]B[3]A[0]A[1]A[2]1......A[n-1]..........................................B[n-1]A[0]A[1]A[2]A[3]......12、代码:
class Solution { public: vector<int> multiply(const vector<int>& A) { vector<int> result(A.size(), 1); vector<int> left(A.size(), 1); vector<int> right(A.size(), 1); for (int i = 0; i < A.size() - 1; i++) { left[i + 1] = left[i] * A[i]; } for (int i = A.size() - 2; i >= 0; i--) { right[i] = right[i + 1] * A[i + 1]; } for (int i = 0; i < A.size(); i++) { result[i] = left[i] * right[i]; } return result; } //------------------空间优化版本-------------------- // vector<int> multiply(const vector<int>& A) { // vector<int> B(A.size(), 1); // for (int i = 0; i < A.size() - 1; i++) { // B[i + 1] = B[i] * A[i]; // } // int tmp = 1; // for (int i = A.size() - 2; i >= 0; i--) { // tmp *= A[i + 1]; // B[i] *= tmp; // } // return B; // } };3、复杂度:
时间复杂度:O(n);
空间复杂度:O(n)。