问题
给定一个数组 A[0,1,…,n-1],请构建一个数组 B[0,1,…,n-1],其中 B[i] 的值是数组 A 中除了下标 i 以外的元素的积, 即 B[i]=A[0]×A[1]×…×A[i-1]×A[i+1]×…×A[n-1]。不能使用除法。
示例
** 输入:** [1,2,3,4,5]
输出: [120,60,40,30,24]
解答
class Solution {
public:
vector<int> constructArr(vector<int>& a) {
int n = a.size(), tmp = 1;
vector<int> res(n, 1);
for (int i = 1; i < n; i++) // 存储左端的所有乘积
res[i] = res[i - 1] * a[i - 1];
for (int i = n - 2; i >= 0 ; i--) {
tmp *= a[i + 1]; // tmp为右端乘积,只需要常数保存即可
res[i] *= tmp;
}
return res;
}
};
重点思路
如果题目没有限制不能使用除法,那么这道题只需要常数空间与一次遍历即可完成,具体做法就是resB = resA / B * A
,可以看出,前后乘积是有关系的,这种题很明显需要使用动态规划。我们可以使用一个dp数组,从左到右遍历保存当前位置左端所有乘积;再使用一个常数,从右到左遍历得到当前位置右端的乘积(因为可以在第二次遍历的时候直接输出结果,所以只需要一个常数保存即可)。比较好想的做法是使用两个dp数组保存所有左端乘积和所有右端乘积,再使用一次遍历使用两个dp相乘得到结果,当然这样就会多耗费一点空间。