一、题目
给你一个整数数组 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]
二、思路
一开始根本想不到用什么模板套,后面看了眼标签有前缀和,但忘记怎么套的了就硬着头皮写了,思路就是创建一个前缀积数组和一个后缀积数组,然后就嗯递归计算,最后相乘得到最后的ans
结果写的就很拉,时间复杂度倒也是O(n),但跑的很慢
三、代码
class Solution {
private:
vector<int> left;
vector<int> right;
vector<int> ans;
public:
void leftplus(int index,vector<int>& nums){
if(index>nums.size()-2) return; //终止
left.push_back(nums[index]*left[index-1]);
leftplus(index+1,nums);
return;
}
void rightplus(int index,vector<int>& nums){
if(index<1) return; //终止
right[index]=nums[index]*right[index+1];
rightplus(index-1,nums);
return;
}
vector<int> productExceptSelf(vector<int>& nums) {
left.push_back(nums[0]); //前缀积数组初始化
leftplus(1,nums);
right.assign(nums.size(), 1); //后缀积数组初始化
right[nums.size()-1]=nums[nums.size()-1];
rightplus(nums.size()-2,nums);
ans.push_back(right[1]);
for(int i=1;i<nums.size()-1;i++){
ans.push_back(left[i-1]*right[i+1]);
}
ans.push_back(left[left.size()-1]);
return ans;
}
};
拿示例1来说就是要算ans[1]的话就用left[1-1]和right[1+1]乘积就行了,因为最多乘nums.size()-1个数,所以ans直接取left的末尾和right的开始即可

四、题解
题解:
class Solution {
public:
vector<int> productExceptSelf(vector<int>& nums) {
int n = nums.size();
vector<int> res(n, 1);
int l = 1;
for (int i=0; i<n; i++) {
res[i] = l;
l *= nums[i];
}
int r = 1;
for (int i =n-1; i>=0; i--) {
res[i] *= r;
r *= nums[i];
}
return res;
}
};
最聪明的做法,先从前往后将数组都按前缀积乘好,再从后往前用后缀积乘
1158

被折叠的 条评论
为什么被折叠?



