Leetcode daily question - 238. The product of arrays other than itself (interview classic 150 questions)

1. Topic description and requirements

238. Product of Arrays Except Self - LeetCode

topic description

Given an integer array nums, return an array answer where answer[i] is equal to the product of all elements in nums except nums[i].

The topic data guarantees that the product of all prefix elements and suffixes of any element in the array nums is within the range of 32-bit integers.

Please don't use division and solve this problem in O(n) time complexity.

example

Example 1:

输入: nums = [1,2,3,4]
输出: [24,12,8,6]

Example 2:

输入: nums = [-1,1,0,-3,3]
输出: [0,0,9,0,0]

hint

  • 2 <= nums.length <= 105
  • -30 <= nums[i] <= 30
  • Ensure that the product of all prefix elements and suffixes of any element in the array nums is within the range of 32-bit integers

2. Problem-solving ideas

General idea:

       First analyze the title, we can see that the title requires us to calculate the product of all elements in the given array except each element itself, and store this product in the answer array in turn . Based on this requirement, we can think of using a double for loop to solve it, but the title requires us to complete it within O(n) time complexity . Based on this requirement, we can think of using a for loop to calculate the product of the entire array and then divide it by Corresponding elements, but the title says that division cannot be used . Therefore, we need to find the final result on the basis of using at most one layer of for loop and not using division.

      We can analyze in this way, whether the numbers other than each element itself are distributed on the left and right sides respectively. The difficulty when we seek the corresponding answer lies in skipping the number itself . Then can we consider using the corresponding elements as the dividing line, and then calculate the product of all the elements on the left and the product of all the elements on the right , and then multiply these two products to get the final result. Because we only need to ask for all the left or right, there is no need to skip , so we can use a layer of for loop to get the result directly. Obviously, the left element product and the right element product corresponding to the record also use arrays to store data.

       The first element and the last element have no left (right) elements, so when calculating the product on the left, i starts from 1, and when calculating the product on the right, i starts from numsSize-2. The formula for calculating the left product is left[i]=left[i-1]*nums[i-1] . The meaning of left[i] refers to the product of the left element of the element subscripted i in the array, so the left product of the current element can be obtained by multiplying the product on the left of the previous number by the previous number. The same goes for the right side, right[i]=right[i+1]*nums[i+1] . After calculating them separately, directly multiply the two results together and assign the value to the answer array.

Specific steps:

① Define two arrays used to store the results and the final array to be returned

② Find the product of all elements on the left of each element and store it in the left array

③ Find the product of all elements on the right of each element and store it in the right array

④ Find the product of the left product and the right product, and store it in the answer array

⑤ Return the answer array


3. Specific code [C language]

/**
 * Note: The returned array must be malloced, assume caller calls free().
   意思是:返回的数组要利用malloc申请空间
 */
int* productExceptSelf(int* nums, int numsSize, int* returnSize){
    //要求计算除自身以外数组的乘积,如果不限制时间复杂度则可以直接利用双重循环求结果
    //但题目要去时间复杂度为O(n),因此我们最多只能够使用一层for循环
    //所要得到的乘积可以转变成分别求其左右两边的乘积后相乘的结果。
    int left[numsSize];//用来存储每个数的左边乘积
    int right[numsSize];//用来存储每个数的右边乘积
    *returnSize = numsSize;//返回数组的大小与原数组相等
    int * answer = (int *)malloc(sizeof(int) * numsSize);//为answer数组申请空间

    //左乘积
    left[0] = 1;//相乘而不是加减,所以初始化为1
    //第一个元素左边没有数据,因此从下标为1的元素开始计算
    for(int i = 1; i < numsSize; i++)
    {
        left[i] =  left[i-1] *  nums[i-1];//计算不包括自身在内的左边的数的乘积
    }

    //右乘积
    right[numsSize-1] = 1;
    //最后一个元素的右边没有数据,因此从下标为numsSize-2开始计算
    for(int i = numsSize-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;
}

Guess you like

Origin blog.csdn.net/m0_59800431/article/details/131656783