leetcode 238. 除自身以外数组的乘积
问题描述
给你一个长度为 n 的整数数组 nums,其中 n > 1,返回输出数组 output ,其中 output[i] 等于 nums 中除 nums[i] 之外其余各元素的乘积。
示例:
输入: [1,2,3,4]
输出: [24,12,8,6]
提示:题目数据保证数组之中任意元素的全部前缀元素和后缀(甚至是整个数组)的乘积都在 32 位整数范围内。
说明: 请不要使用除法,且在 O(n) 时间复杂度内完成此题。
进阶:
你可以在常数空间复杂度内完成这个题目吗?( 出于对空间复杂度分析的目的,输出数组不被视为额外空间。)
1.代码(使用除法)
如果数组中没有零元,那么结果就是这几个数的乘积除以自己就好了,如果有一个零元,乘积是所有非零元的乘积,除了零元对应饿结果是这个乘积外,其余非零元对应的结果都是零,如果有大于一个零元,除了自己的以外一定至少含有一个零元,所以每个元素对应的结果都是零。
class Solution {
public:
vector<int> productExceptSelf(vector<int>& nums) {
int prod = 1,i,n = nums.size(),nnz = 0;
vector<int> out(n,0);
for(i = 0; i < n; i++)
{
if(nums[i]!= 0)
prod *= nums[i],
nnz++;
}
if(nnz == 0)return out;
if(n - nnz == 0)//没有0的情况
{
for(i = 0; i < n; i++)
out[i] = prod/nums[i];
}
else if(n - nnz == 1)//有一个0的情况
{
for(i = 0; i < n; i++)
if(nums[i] == 0)
out[i] = prod;
}
return out;
}
};
结果
执行用时 :24 ms, 在所有 C++ 提交中击败了30.65%的用户
内存消耗 :15.3 MB, 在所有 C++ 提交中击败了5.23%的用户
2.代码(不使用除法)
记录下第i个位置以前的数的乘积及之后的数的乘积,再乘起来就好了,但是空间复杂度为\(O(N)\).
class Solution {
public:
vector<int> productExceptSelf(vector<int>& nums) {
int i, n = nums.size();
vector<int> front(n,1);
vector<int> back(n,1);
vector<int> out(n,1);
for(i = 0; i < n-1; ++i)front[i+1] = front[i]*nums[i];
for(i = n-1; i > 0; --i)back[i-1] = back[i]*nums[i];
for(i = 0; i < n; ++i)out[i] = back[i]*front[i];
return out;
}
};
结果:
执行用时 :24 ms, 在所有 C++ 提交中击败了30.65%的用户
内存消耗 :16 MB, 在所有 C++ 提交中击败了5.23%的用户
3.代码(代码2空间的优化)
class Solution {
public:
vector<int> productExceptSelf(vector<int>& nums) {
int i, n = nums.size(),back = 1;
vector<int> out(n,1);
for(i = 1; i < n; ++i)out[i] = out[i-1]*nums[i-1];
for(i = n-1; i >= 0; --i)
{
out[i] *= back;
back *= nums[i];
}
return out;
}
};
结果:
执行用时 :24 ms, 在所有 C++ 提交中击败了30.65%的用户
内存消耗 :15.3 MB, 在所有 C++ 提交中击败了5.23%的用户