【剑指Offer-66】构建乘积数组

问题

给定一个数组 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相乘得到结果,当然这样就会多耗费一点空间。

上一篇:20201214 集合及其运算


下一篇:全球66家央行中10%的央行进入数字货币测试阶段