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

129 阅读1分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第16天,点击查看活动详情

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

238. 除自身以外数组的乘积 - 力扣(LeetCode)

给你一个整数数组 nums,返回 数组 answer ,其中 answer[i] 等于 nums 中除 nums[i] 之外其余各元素的乘积 。

题目数据 保证 数组 nums之中任意元素的全部前缀元素和后缀的乘积都在 32 位 整数范围内。

请不要使用除法,且在 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 位 整数范围内

问题解析

一开始想这题用除法来写就很简单了,我们直接遍历一遍数组,把所有的数都乘起来记作ans,然后对于第i个位置,除它以外的数的乘积就是ans除去arr[i]。

但是如果数组有0,那就要额外记录一些变量(比如只记录非0数的乘积,然后记录其它哪些位置是0),会变得麻烦.何况这题不能用除法。

但是我们思路其实没问题,我们就是把所有数的乘积去掉第i个位置上的数就能得到结果。

我们可以准备一个前缀积数组fl和一个后缀积数组fr,fl[i]表示第i个位置前全部数的乘积,fr[i]表示第i个位置后全部数的乘积。

那么对于第i个位置的结果,其实就是fl[i]* fr[i]。

AC代码

class Solution {
public:
    int fl[100050],fr[100050];
    vector<int> productExceptSelf(vector<int>& nums) {
        int n=nums.size();
        fl[0]=1,fr[n+1]=1;
        //下标有所改动,笔者习惯从1开始
        for(int i=1;i<=n;i++)
        {
            fl[i]=fl[i-1]*nums[i-1];
        }
        for(int i=n;i>=1;i--)
        {
            fr[i]=fr[i+1]*nums[i-1];
        }
        vector<int>v(n);
        for(int i=0;i<n;i++)
        {
            v[i]=fl[i]*fr[i+2];
        }
        return v;
    }
};