今天做到两道很有意思的题目,也是收获颇丰,了解到了前缀和的概念,以及malloc怎么开辟二维数组的办法。
关于这道题我们其实只要用一次循环把目标数ret[i]左面的所有元素的乘积以及它右面所有元素的乘积储存到l和r里面,在这里需要注意的是,l需要将l[0]初始化为1,因为nums[0]左面没有元素,同理,将r[numsSsize-1]也初始化成1,在循环过程中l数组是正序进行乘积,r数组是逆序。最后在进行一次循环,将结果储存到需要返回的数组ret中,且ret=l[i]*r[i]。时间按复杂度:O(n),空间复杂度O(2n)。代码如下
int* productExceptSelf(int* nums, int numsSize, int* returnSize){
int i=0;
int *l=(int*)malloc(sizeof(int)*numsSize);
int *ret=(int*)malloc(sizeof(int)*numsSize);
l[0]=1;
int *r=(int*)malloc(sizeof(int)*numsSize);
r[numsSize-1]=1;
for(i=1;i<numsSize;i++)
{
l[i]=nums[i-1]*l[i-1];
r[numsSize-i-1]=nums[numsSize-i]*r[numsSize-i];
}
*returnSize=numsSize;
for(i=0;i<numsSize;i++)
{
ret[i]=l[i]*r[i];
}
return ret;
}
后面我看了最后的进阶,想到,我们在计算l和r两个数组时,算到中间部分再往后那就会两部分发生重叠,借鉴答案后明白,可以直接在结果数组上直接操作,具体方法是,先将未优化代码的l先行计算存储到ret中 然后建立变量r在反向循环在r身上乘以nums数组中的元素以达到后缀积的作用,这样也可以得到最终结果,时间复杂度O(n)空间复杂度O(1).代码如下:
int* productExceptSelf(int* nums, int numsSize, int* returnSize){
int *ret=(int*)malloc(sizeof(int)*(numsSize));
*returnSize=numsSize;
ret[0]=1;
int i=0;
int right=1;
for(i=1;i<numsSize;i++)
{
ret[i]=ret[i-1]*nums[i-1];
}
for(i=numsSize-2;i>=0;i--)
{
right*=nums[i+1];
ret[i]=ret[i]*right;
}
return ret;
}
最后还有一个收获就是二维数组开辟的小知识点(此前困扰了我好久)在这里举一个int arr[]10[10]数组开辟的方法,部分代码如下:
int** arr=(int**)malloc(sizeof(int*)*10);
int i=0;
for(i = 0 ;i < 10 ;i++)
{
arr[i]=(int*)malloc(sizeof(int)*10);
}