题目链接
力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台
题目解析
使用前缀和进行解决该题,只不过与之前前缀和不同的是这个题目计算前缀和的时候不需要计算当前元素,也就是当前位置前缀和的值其实是不包含当前元素的前缀和。
我们算出该位置的前缀和(不包含当前元素),后缀和(不包含当前元素)。然后再相乘。
解题方法
法一:我们直接定义三个数组,一个记录最终结果,一个计算前缀和,一个计算后缀和。
法二:只需要定义一个数组,先计算前缀和,然后使用一个变量记录后缀和与之相乘,只需要遍历的过程中乘上后缀和即可。
代码
法一
class Solution
{
public:
vector<int> productExceptSelf(vector<int>& nums)
{
int n=nums.size();
vector<int> answer(n),answer_front(n),answer_tail(n);
answer_front[0]=nums[0];
answer_tail[n-1]=nums[n-1];
for(int i=1;i<n;i++)
{
answer_front[i]=answer_front[i-1]*nums[i];
}
for(int i=n-2;i>=0;i--)
{
answer_tail[i]=answer_tail[i+1]*nums[i];
}
for(int i=0;i<n;i++)
{
// 注意处理第一个元素与第二个元素
if(i==0)
answer[i]=answer_tail[i+1];
else if(i==n-1)
answer[i]=answer_front[n-2];
else
answer[i]=answer_front[i-1]*answer_tail[i+1];
}
return answer;
}
};
法二
class Solution
{
public:
vector<int> productExceptSelf(vector<int>& nums)
{
int n=nums.size();
vector<int> ret(n);
// 先算前缀和
// 第一个前缀和设为1,目的是为了不影响后面数据的计算
ret[0]=1;
// 需要注意的是我们所计算的前缀和是不包含自身的
for(int i=1;i<n;i++)
// 当前位置的前缀和等于上一个数的前缀和*上一个数组的元素
ret[i]=ret[i-1]*nums[i-1];
// 再计算后缀和
// 使用k来记录后缀和,设为1为了不影响前边的后缀和数据
int k=1;
for(int i=n-2;i>=0;i--)
{
// 每次遍历都及时更新k
k*=nums[i+1];
// 更新ret[i]
ret[i]=ret[i]*k;
}
// 此时数组ret中的元素就是当前元素的前缀和*后缀和
return ret;
}
};