题目链接:238. 除自身以外数组的乘积
题目描述:
给你一个整数数组
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 位 整数范围内进阶:你可以在
O(1)
的额外空间复杂度内完成这个题目吗?( 出于对空间复杂度分析的目的,输出数组 不被视为 额外空间。)
解法(前缀和数组):
算法思路:
注意题目的要求,不能使用除法,并且要在 0(N) 的时间复杂度内完成该题。那么我们就不能使 用暴力的解法,以及求出整个数组的乘积,然后除以单个元素的方法。
继续分析,根据题意,对于每一个位置的最终结果 ret[i],它是由两部分组成的:
❍ nums[0] * nums[1] * nums[2] * ... * nums[i-1]
❍ nuts[i + 1] * nums[i+2] * ... *nums[n-1]
于是,我们可以利用前缀和的思想,使用两个数组before和after,分别处理出来两个信息: ❍
❍ before 存[0,i-1] 的积 , after存[i+1,n-1]的积
❍ ret[i] = before[i] * after[i] ,ret即为结果
本题与**724. 寻找数组的中心下标类似,就不多介绍啦,也是建立函数关系第i个位置前面的积 = 第i-1个位置前面的积 * 第i-1个位置的数据。after数组从后向前遍历,细节问题就是vector要初始化为1,不然初始化为0,这里是乘,将一直会是0
class Solution { public: vector<int> productExceptSelf(vector<int>& nums) { int n = nums.size(); //预处理前缀积和后缀积 vector<int> before(n,1); vector<int> after(n,1); for(int i = 1; i < n; i++){ before[i] = before[i-1] * nums[i-1]; } for(int i = n-2; i >= 0; i--){ after[i] = after[i+1] * nums[i+1]; } //使用前缀积和后缀积 vector<int> ret(n); for(int i = 0; i < n; i++){ ret[i] = before[i] * after[i]; } return ret; } };