题目
给你一个长度为 n 的整数数组 nums,其中 n > 1,返回输出数组 output ,其中 output[i] 等于 nums 中除 nums[i] 之外其余各元素的乘积。
示例
输入: [1,2,3,4]
输出: [24,12,8,6]
题目链接
题目分析
实际上一个除自身以外数组的乘积就是一个数的左边所有数和右边所有数字的乘积,因此,我们只要用两个数组L
和R
分别储存当前坐标左边数字的乘积和右边数字的乘积,最后按照坐标依次相乘即可。
首先初始化两个数组:
int len = nums.size();
vector L(len, 1);
vector R(len, 1);
for (int i = 1; i < len; i++) {
L[i] = L[i - 1] * nums[i - 1];
}
for (int i = len - 2; i >= 0; i--) {
R[i] = R[i + 1] * nums[i + 1];
}
然后得到最后的结果:
vector res;
for (int i = 0; i < len; i++){
res.push_back(L[i] * R[i]);
}
return res;
但是通过上述的过程我们可以明显发现,在计算并储存了左乘积以后,再次储存右乘积对空间明显浪费,所以我们可以优化空间复杂度,全程只使用一个数组,储存左乘积,并在此数字的基础上运算最后结果返回。
int R = 1;
for (int i = len - 2; i >= 0; i--) {
R *= nums[i + 1];
res[i] *= R;
}
return res;
题目解答
常数级空间复杂度
int* productExceptSelf(int* nums, int numsSize, int* returnSize){
*returnSize = numsSize;
int* res = (int*)calloc(numsSize, sizeof(int));
res[0] = 1;
for (int i = 1; i < numsSize; i++) {
res[i] = res[i - 1] * nums[i - 1];
}
// 然后计算右边
int R = 1;
for (int i = numsSize - 2; i >= 0; i--) {
R *= nums[i + 1];
res[i] *= R;
}
return res;
}