题目要求:
该方法分以下几步:
#include<stdio.h>
#include<stdlib.h>
int* productExceptSelf(int* nums, int numsSize, int* returnSize) {
int* answer = (int*)calloc(numsSize, sizeof(int));
*returnSize = numsSize;
int sum = 1;
for (int i = 0; i < numsSize; i++)
{
sum *= nums[i]; //求所有元素的乘积
}
for (int i = 0; i < numsSize; i++)
{
answer[i] = sum / nums[i];
}
return answer;
}
int main()
{
int arr[] = { 1,2,3,4 };
int sz = sizeof(arr) / sizeof(arr[0]);
int count = 0;
int* ret = productExceptSelf(arr, sz, &count);
for (int i = 0; i < count; i++)
{
printf("%d", *(ret + i));
if (i != count - 1)
{
printf(",");
}
}
free(ret);
ret = NULL;
return 0;
}
相较于第一种方法,我们不必将所有数字的乘积除以给定索引处的数字得到相应的答案,而是利用索引左侧所有数字的乘积和右侧所有数字的乘积(即前缀与后缀)相乘得到答案。这也是题目中暗示我们的
该方法分以下几步:
Left[i] 代表的是 i 左侧所有数字的乘积,Right[i] 代表的是 i 右侧所有数字的乘积。
#include<stdio.h>
#include<stdlib.h>
int* productExceptSelf(int* nums, int numsSize, int* returnSize) {
int* answer = (int*)calloc(numsSize, sizeof(int));
*returnSize = numsSize;
int Left[numsSize];
int Right[numsSize];
Left[0] = 1;
Right[3] = 1;
for (int i = 1; i < numsSize; i++)
{
Left[i] = Left[i - 1] * nums[i - 1];
}
for (int i = 2; i >= 0; i--)
{
Right[i] = Right[i + 1] * nums[i + 1];
}
for (int i = 0; i < numsSize; i++)
{
answer[i] = Left[i] * Right[i];
}
return answer;
}
int main()
{
int arr[] = { 1,2,3,4 };
int sz = sizeof(arr) / sizeof(arr[0]);
int count = 0;
int* ret = productExceptSelf(arr, sz, &count);
for (int i = 0; i < count; i++)
{
printf("%d", *(ret + i));
if (i != count - 1)
{
printf(",");
}
}
free(ret);
ret = NULL;
return 0;
}
复杂度分析:
由于输出数组不算在空间复杂度内,而且我们的answer数组只有最后才被用到,所以我们可以先将 Left 或 Right 数组用answer数组来计算。
该方法分为以下几步:
#include<stdio.h>
#include<stdlib.h>
int* productExceptSelf(int* nums, int numsSize, int* returnSize) {
int* answer = (int*)calloc(numsSize, sizeof(int));
*returnSize = numsSize;
int left[numsSize];
int right[numsSize];
answer[0] = 1;
int R = 1;
//先求前缀之积
for (int i = 1; i < numsSize; i++)
{
answer[i] = answer[i - 1] * nums[i - 1];
}
//求后缀之积与answer
for (int i = numsSize - 1; i >= 0; i--)
{
// 对于下标 i,左边的乘积为 answer[i],右边的乘积为 R
answer[i] = answer[i] * R;
// R 需要包含右边所有的乘积,所以计算下一个结果时需要将当前值乘到 R 上
R *= nums[i];
}
return answer;
}
int main()
{
int arr[] = { 1,2,3,4 };
int sz = sizeof(arr) / sizeof(arr[0]);
int count = 0;
int* ret = productExceptSelf(arr, sz, &count);
for (int i = 0; i < count; i++)
{
printf("%d", *(ret + i));
if (i != count - 1)
{
printf(",");
}
}
free(ret);
ret = NULL;
return 0;
}
复杂度分析
目前想到的方法就这些,后续想到会补充。