Leetcode: 238. The product of arrays other than itself [Super detailed solution]

Pure C language implementation (even Xiaobai can understand)

topic

Given an array of integers  nums, return  the array  answer , which  answer[i] is equal to  nums the  nums[i] product of the remaining elements  .

The title data  guarantees thatnums the products of all prefix elements and suffixes of any element in    the array  are within the range of 32-bit  integers.

Please do not use division and   complete this problem within the time complexity.O(n)

Difficulty: Moderate

Topic link: 238. Product of arrays other than itself

problem solving ideas 

Since this question cannot use division, so refer to the method of explaining a left-right product list to create two new arrays a, b. One is used to record the product from left to right (similar to the idea of ​​​​dynamic programming) a and the other is to record from right to right. The left product b (note that b is multiplied from right to left) and the leftmost end of a is 1, and the rightmost end of b is 1. So at the end, only a*b is needed for example, ans[0]=a [0]*b[0] a[0]=1 b[0]=The product of all elements except nums[0]

code display 

/**
 * Note: The returned array must be malloced, assume caller calls free().
 */
int* productExceptSelf(int* nums, int numsSize, int* returnSize){
    //前缀积*后缀积 == 除自身以外数组的乘积
    int *answer = (int*)malloc(sizeof(int)*numsSize);
    answer[0] = 1;//第一个数字前面没有数字了,第一个数字的前缀是1
    int i = 0;
    //前缀积
    for(i = 1;i<numsSize;i++)
    {
        answer[i] = answer[i-1]*nums[i-1];
    }
    //后缀积
    int rp[numsSize];//用来记录后缀积
    rp[numsSize-1] = 1;//因为最后边的数的后缀只能是1
    for(i = numsSize -1-1;i>=0;i--)
    {
        rp[i] = rp[i+1] * nums[i+1]; 
    }
    for(i = 0;i<numsSize;i++)
    {
        answer[i] = answer[i] * rp[i];//前缀积*后缀积
    }
    *returnSize = numsSize;//返回数组的大小
    return answer;//返回数组answer
}

 【Super detailed analysis】

First of all, this is a function implementation, and we must pay attention to the parameters of the function. (int * nums, this is the address of the array passed, numsSize, this is the size of the array, *numsSize, is the size of the array to be returned after use)

Next comes code analysis

Because we want to return the array answer according to the meaning of the title, we can use malloc() to dynamically allocate memory space

int *answer = (int*)malloc(sizeof(int)*numsSize);

The meaning of this line of code is: create a pointer variable answer, and use malloc()the function to dynamically allocate a memory space with a size of sizeof(int)*numsSizebytes. Among them, sizeof(int)refers to intthe number of bytes occupied by the type in the current system, and numsSizeis a variable indicating the number of elements that need to be allocated. malloc()Assign the returned memory address to the pointer variable by int*casting it to answer. numsSizeIn this way, integers can be stored in dynamically allocated memory space .

The meaning of the title is to calculate the product of the array other than itself, we use the result == prefix product * suffix product according to the problem-solving idea

For example, 1 2 3 4 5, here I take the product of arrays other than 3 (1*2*4*5), because the title requires not to use division, and  O(n) complete this question within the time complexity. So (1*2*4*5) becomes 1*2 (prefix product) * 4*5 (suffix product),

This way (1*2)*(4*5)

prefix product

Here we use the array [1, 2, 3, 4], here we need to pay attention that the prefix product of the first element of the array and the suffix product of the last element of the array are 1. We use the answer array to receive

answer[0] = 1;

(Although the answer array needs to return the result, we can first use the product of the prefix, then use another array to get the product of the suffix, and then multiply the elements of the two arrays to get the result. This can reduce a certain amount of memory consumption)

Next, find the prefix product (because we know that the prefix product of the first element of the array is 1), so the calculation starts from the second element

    //前缀积
    for(i = 1;i<numsSize;i++)
    {
        answer[i] = answer[i-1]*nums[i-1];
    }

The next requirement is nums[1], which is the prefix product of the second element

 

Because only one element in front of nums[1] is 1, so the prefix product of nums[1] is 1

Look at nums[2]

 At this time, you may have such a question, why nums[1]*answer[1] instead of nums[0] * nums[1]

Here you need to know that the product must be multiplied continuously. You can understand the product of each stage stored in the answer array (in fact, it is the product of the prefix corresponding to each nums array)

numbers[3]

 suffix product

    //后缀积
    int rp[numsSize];//用来记录后缀积
    rp[numsSize-1] = 1;//因为最后边的数的后缀只能是1
    for(i = numsSize -1-1;i>=0;i--)
    {
        rp[i] = rp[i+1] * nums[i+1]; 
    }

This declares an rp array in advance to record the suffix product, and the suffix product of the last element of the array is 1

rp[1]

 rp[2]

rp[3]

prefix product * suffix product

    for(i = 0;i<numsSize;i++)
    {
        answer[i] = answer[i] * rp[i];//前缀积*后缀积
    }

Finally, the answer array is multiplied by the corresponding elements of the rp array (answer[i] = answer[i] * rp[i])

 The size of the answer array here is the same as the size of the nums array. Return numsSize, and the array returns answer.

Guess you like

Origin blog.csdn.net/qq_72505850/article/details/132470594