C语言每日一题:8.除自身以外数组的乘积。

题目:

C语言每日一题:8.除自身以外数组的乘积。_第1张图片
题目:

思路一:

(先不考虑题目的要求循序渐进的方法)
1.动态开辟数组,初始化数组内容为全1.
2.使用双for循环去给answer赋值。
3.在相同位置不去*=对应的下标位置的数组值,而是*=1;

int* productExceptSelf(int* nums, int numsSize, int* returnSize){
            //开辟数组
            int* answer=(int*)calloc(1,sizeof(int)*numsSize);
            for(int b=0;b<numsSize;b++)
            {
                answer[b]=1;
            }
            int n=numsSize;
            //循环遍历
            for(int i=0;i<n;i++)
            {
                for(int j=0;j<n;j++)
                {
                    if(j!=i)
                    {
                        (answer[i])*=(nums[j]);
                    }
                }
            }
            *returnSize=n;
            return answer;
}

C语言每日一题:8.除自身以外数组的乘积。_第2张图片

总结:时间复杂度是O(N^2)空间复杂度 O(1)(不包括开辟的数组);
那么非常明显这个算法的时间复杂度比较高在遇到非常大的测试用例的时候就超出时间的限制。

思路二:

(假设可以使用除法)
1.求nums所有元素的乘积记录下来为sum。
2.给anser赋值只需要把这个位置的nums的值除去。
3.如果nums的这个位置是0的话不是我们计算的sum.
4.在nums中存在0,和不存在0.分两个情况讨论。
5.如果存在0的话需要重新遍历数组去求乘积的值。
6.在数组中如果有1个0存在那么这个answer只有一个nums是0的这个位置不为0,其他的位置都是0.
7.如果nums中存在两个0那么answer就全部都是0.

int* productExceptSelf(int* nums, int numsSize, int* returnSize) {
    //开辟数组
    int* answer = (int*)calloc(numsSize,sizeof(int));
    //计算乘积
    int sum = 1;
    for (int i = 0; i < numsSize; i++)
    {
        sum *= nums[i];
        answer[i] = 1;
    }
    //给answer赋值
    for (int j = 0; j < numsSize; j++)
    {
        if (sum == 0)
        {
            if (nums[j] == 0)
            {
                for (int i = 0; i < numsSize; i++)
                {
                    if (i == j)
                    {
                        continue;
                    }
                    answer[j] *= nums[i];
                }
            }
            else
            {
                answer[j] = 0;
            }

        }
        else
        {
            if (nums[j] == 0)
            {
                answer[j] = sum;
                continue;
            }
            answer[j] = (sum / nums[j]);
        }
    }

    *returnSize = numsSize;
    return answer;
}
控制台

时间复杂度:
1.nums中有0的时候F(N)N^2+N== O(N^2)==
2.nums中没有0的时候F(N)=2N O(N^2)
思路一和思路二比较的话,思路二的平均复杂度是比较底的。
运行结果是可以通过的。

C语言每日一题:8.除自身以外数组的乘积。_第3张图片

思路三:

思路一和二是比较好想的方法,但是这个题目不允许使用除法。
1.给anver循环赋值从左到右依次把乘等的数值赋值到answer上。
2.从右到左把缺少的项再乘等进去。
3.answer就赋值完成了。

C语言每日一题:8.除自身以外数组的乘积。_第4张图片

nt* productExceptSelf(int* nums, int numsSize, int* returnSize){
            //开辟数组
            int* answer=(int*)malloc(sizeof(int)*numsSize);
            int n=numsSize;
            //循环遍历
            int i=0;

            //给answer赋从左到右,开始位置左边没有值初始化red_left==1
            int red_left=1;
            for(i=0;i<n;i++)
            {
                answer[i]=red_left;
                red_left*=nums[i];
            }
            //给answer赋从右到左,末尾位置右边没有值初始化red_right==1
            int j=0;
            int red_right=1;
            for(j=n-1;j>=0;j--)
            {
                 answer[j]*=red_right;
                 red_right*=nums[j];   
            }
            *returnSize=n;
            return answer;
}

总结:时间复杂度O(N)

对于这个题目的前面两个方法是没有按照题目要求来写的,出现时间复杂度的问题,除法的方法是可以通过的但是他的代码的复杂度是比较高的,所以在写这样有一些关于方法和复杂度的要求的题目的时候就需要效率非常高的算法,不敢不按照题目要求去写题目,对你是没有什么好处的,测试用例和题目要求是具有关联。不按照题目要求是很可能通不过测试用例的。{关于思路三我想说这样的算法需要你去好好的观察和写过非常多的题目才可以对有一些要求的题目得心应手有自己的方法而不是去暴力求解和不按照题目要求去写题目。}

希望文章可以帮助到每一个在刷题的小伙伴!!!!!!。
希望可以你在这一方面的困惑。

你可能感兴趣的:(c语言,开发语言)