-
题目:剑指Offer66.构建乘积数组
输入一个数组a,要返回一个数组b,且b[ i ]=数组a中除了a[ i ]以外其它所有元素的乘积 -
思路:
1.dp两次遍历:O(n),O(1)
正常思路是:b[ i ] 相当于在b [ i - 1 ] 的基础上,乘a [ i - 1 ] ,除a [ i ] ,这样只需遍历一次O(n);
本题不能使用除法,想到从左往右遍历,若只看b [ i ]和b [ i - 1 ]左侧的区别,就是在b [ i - 1]基础上 多乘了个a [ i - 1 ];但右侧的区别是除了个b [ i ],但我们若倒过来想,即b[ i - 1 ]在b [ i ]的基础上多乘了个a [ i ],因此我们可以从左往右遍历先计算左侧乘积,再从右往左遍历计算右侧乘积,这样只使用乘法;
class Solution {
public:
vector<int> constructArr(vector<int>& a) {
int n = a.size();
vector<int> b(n, 1);//b[i]=a[i]左侧的乘积*a[r]右侧的乘积=a[0]*...*a[i-1]*a[i+1]*...*a[n-1]
for (int i = 0, l = 1; i < n; ++i) {//从左往右遍历:求出a[i]侧的乘积
b[i] *= l;
l *= a[i];
}
for (int i = n - 1, r = 1; i >= 0; --i) {//从右往左遍历:再乘上a[i]右侧的乘积
b[i] *= r;
r *= a[i];
}
return b;
}
};