持续创作,加速成长!这是我参与「掘金日新计划 · 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;
}
};