238. Product of Array Except Self

来源:互联网 发布:青蛙城 知乎 编辑:程序博客网 时间:2024/06/03 21:32

这道题给出一个数组,要求返回一个一样大小的数组,其中的每一个元素是原数组中除了这个元素之外的所有元素的乘积。要求不能用除法,时间为O(n)。常数空间。

这道题如果不要求常数空间,我用了类似动态规划的方法,定义两个数组left2right和right2left,left2right[i]是0~i个数的乘积,right2left[i]是i~n-1个数的乘积。那么最后的数组res[i]就是left2right[i] * right2left[i+1]即可。但是显然常数空间这个不满足。代码如下:

class Solution {public:    vector<int> productExceptSelf(vector<int>& nums) {        int n = nums.size();        vector<int> left2right(n, nums[0]);        vector<int> right2left(n, nums[n-1]);        for(int i = 1; i < nums.size(); ++i){            left2right[i] = left2right[i-1] * nums[i];        }        for(int i = n-2; i >= 0; --i){            right2left[i] = right2left[i+1] * nums[i];        }        vector<int> res(n, 1);        for(int i = 0; i < n; ++i){            int left = i-1 < 0 ? 1 :left2right[i-1];            int right = i+1 >= n ? 1 : right2left[i+1];            res[i] = left * right;        }        return res;    }};
方法一样,现在必须对空间做优化。我们可以对上面的方法进行空间上的优化,由于最终的结果都是要乘到结果res中,所以我们可以不用单独的数组来保存乘积,而是直接累积到res中,我们先从左往右遍历一遍,res[i]乘nums[i]左边的乘积(不包括nums[i])。然后从右往左遍历一遍,res[i]乘nums[i]右边的乘积(不包括nums[i])。

class Solution {public:    vector<int> productExceptSelf(vector<int>& nums) {        vector<int> res(nums.size(), 1);        for (int i = 1; i < nums.size(); ++i) {            res[i] = res[i - 1] * nums[i - 1];        }        int right = 1;        for (int i = nums.size() - 1; i >= 0; --i) {            res[i] *= right;            right *= nums[i];        }        return res;    }};