题目
给你一个长度为 n 的整数数组 nums,其中 n > 1,返回输出数组 output ,其中 output[i] 等于 nums 中除
nums[i] 之外其余各元素的乘积。
示例:
输入: [1,2,3,4]
输出: [24,12,8,6]
提示:
数据保证数组之中任意元素的全部前缀元素和后缀(甚至是整个数组)的乘积都在 32 位整数范围内。
说明:
请不要使用除法,且在 O(n) 时间复杂度内完成此题。
进阶:
你可以在常数空间复杂度内完成这个题目吗?
( 出于对空间复杂度分析的目的,输出数组不被视为额外空间。)
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/product-of-array-except-self
一共有4个版本
第一版本:超时,每个新数组的值都遍历求出
int* productExceptSelf(int* nums, int numsSize, int* returnSize)
{
*returnSize = numsSize;
if (numsSize <= 1)
{
return nums;
}
int* arr = (int*)malloc(sizeof(int) * numsSize);
int sum = 1;
for (int i = 0; i < numsSize; i++)
{
sum = 1;
for (int j = 0; j < numsSize; j++)
{
if (j != i)
sum *= nums[j];
}
arr[i] = sum;
}
return arr;
}
第二版本:顺利提交,但用了除法(这属于简单题,而不是中等题)
在第一版本的基础上,先算出所有数据相乘结果,再利用除法求出新数组的值
要注意:总乘积为0时的特殊情况
int* productExceptSelf(int* nums, int numsSize, int* returnSize)
{
*returnSize = numsSize;
if (numsSize <= 1)
{
return nums;
}
int* arr = (int*)malloc(sizeof(int) * numsSize);
int sum = 1;
for (int i = 0; i < numsSize; i++)
{
sum *= nums[i];
}
for (int i = 0; i < numsSize; i++)
{
if (nums[i] != 0)
{
arr[i] = sum / nums[i];
}
else
{
int sum1 = 1;
for (int j = 0; j < numsSize; j++)
{
if (j != i)
sum1 *= nums[j];
}
arr[i] = sum1;
}
}
return arr;
}
第三版本,符合题目要求
参考了官方思路:分别用left数组和right数组,保存i左右数据的乘积 写了C代码
注意:为了不超时left数组和right数组都用 *= 来计算
left数组从0开始计算,right数组从numsSize-1开始
int* productExceptSelf(int* nums, int numsSize, int* returnSize)
{
* returnSize=numsSize;
if(numsSize<=1)
{
return nums;
}
int* left = (int*)malloc(sizeof(int) * numsSize);
int* right = (int*)malloc(sizeof(int) * numsSize);
int sumleft = 1;
int sumright=1;
int i,j,k;
for (i = 0; i < numsSize; i++)
{
if(i!=0)
sumleft*=nums[i-1];
left[i]=sumleft;
}
for (i = numsSize-1; i >=0; i--)
{
if(i!=numsSize-1)
sumright*=nums[i+1];
right[i]=sumright;
}
int* sum = (int*)malloc(sizeof(int) * numsSize);
for (int i = 0; i < numsSize; i++)
{
sum[i]=left[i]*right[i];
}
return sum;
}
第四版本:优化第三版本
int* productExceptSelf(int* nums, int numsSize, int* returnSize)
{
*returnSize = numsSize;
if (numsSize <= 1)
{
return nums;
}
int* left = (int*)malloc(sizeof(int) * numsSize);
int sumleft = 1;
int sumright = 1;
int i, j, k;
for (i = 0; i < numsSize; i++)
{
if (i != 0)
sumleft *= nums[i - 1];
left[i] = sumleft;
}
for (i = numsSize - 2; i >= 0; i--)
{
sumright *= nums[i + 1];
left[i] *= sumright;
}
return left;
}