玩命加载中 . . .

238.除自身以外数组的乘积


问题

传送门:https://leetcode.cn/problems/product-of-array-except-self/

给你一个整数数组 nums,返回 数组 answer ,其中 answer[i] 等于 nums 中除 nums[i] 之外其余各元素的乘积 。题目数据 保证 数组 nums之中任意元素的全部前缀元素和后缀的乘积都在 32 位 整数范围内。

不要使用除法,且在$\mathcal{O}(n)$时间复杂度内完成此题。

示例 1:

输入: nums = [1,2,3,4]
输出: [24,12,8,6]

示例 2:

输入: nums = [-1,1,0,-3,3]
输出: [0,0,9,0,0]

提示:

  • 2 <= nums.length <= 105
  • -30 <= nums[i] <= 30
  • 保证 数组 nums之中任意元素的全部前缀元素和后缀的乘积都在 32 位 整数范围内

思路

不妨以一个具体的例子来看看结果是如何得出的。

除自身以外数组乘积可以看作由左右两部分组成

事实上,可以发现每一个元素除开自身以外数组的乘积可以由两部分组成:该元素左侧元素和右侧元素。那么我们可以维护两个前缀积数组,存储到最左侧的元素之积以及最右侧的元素之积即可。具体地,记原数组为$nums[]$,其长度为$n$,则

  • 维护$left[]$数组,其中$left[i]=nums[0]\times nums[1] \times \cdots\times nums[i-1]$
  • 维护$right[]$数组,其中$right[i] = nums[i+1]\times nums[i+2]\times \cdots\times nums[n-1]$

两轮遍历,分别为left数组和right数组赋值即可。

代码

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

文章作者: 鹿卿
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 鹿卿 !
评论
  目录