1

我一直在 leetcode 上尝试这个问题。238. 除自身以外的数组的乘积

给定一个整数数组nums,返回一个数组 answer,使得 answer[i]等于nums除了 nums[i]之外的所有元素的乘积。

nums 的任何前缀或后缀的乘积都保证适合 32 位整数。

您必须编写一个在O(n)时间内运行且不使用除法运算的算法。

示例 1:

Input: nums = [1,2,3,4]

Output: [24,12,8,6]

示例 2:

Input: nums = [-1,1,0,-3,3]
 
 Output: [0,0,9,0,0]

这是我对上述问题的解决方案。

public int[] productExceptSelf(int[] nums) {
   
    int answer[]=new int[nums.length];
    for(int i=0;i<nums.length;i++){
        int prod=1;
        for(int j=0;j<nums.length;j++){
            if(j!=i)
                
                prod=prod*nums[j];
        }
        answer[i]=prod;
    }
    return answer;
}

这是通过 19/20 测试用例。有一个测试用例不起作用,我收到错误“超出时间限制”。

下面给出了失败的测试用例:

Input: [-1,-1,-1,-1,..............];
 
Output: Time limit exceeded.

如果有人可以帮助我对我的代码做哪个版本?

4

4 回答 4

6

我也做 leetcode,它给了你 TLE,因为这不是他们期望的解决方案。这是正确的,但它需要 O(N*N) 次运算来计算,O(N) 有更好的解决方案,

public int[] productExceptSelf(int[] nums) {
          
        int output[] = new int[ nums.length];
        
        output[0] = 1;

        // left prefix product
        for(int i=1;i<nums.length;i++){
             output[i] = output[i-1] * nums[i-1];
        }
        
        int product = 1;

        for(int i=nums.length-1;i>=0;i--){
            
            output[i] = output[i] * product;
            
            product*= nums[i];
        }
        
        return output;
}
于 2021-07-29T06:19:36.490 回答
1

该解决方案也给出了 O(N) 但仅使用 1 个周期。

public int[] productExceptSelf(int[] nums) {
    int[] res = new int[nums.length];
    res[0] = 1;
    res[nums.length-1] = 1;
    int n = 1;
    int k = nums.length-2;
    int fromLeft = 1;
    int fromRight = 1;
    while(n < nums.length) {
        fromLeft  = nums[n-1] * fromLeft;
        fromRight = nums[k+1] * fromRight;
        if (n < k) {
            res[n] = fromLeft;
            res[k] = fromRight;
        } else {
            if (n == k) {
                res[n] = fromLeft * fromRight;
            } else {
                res[n] = fromLeft  * res[n];
                res[k] = fromRight * res[k];
            }
        }
        n++;
        k--;
    }
    return res;
}
于 2021-11-25T02:11:45.977 回答
1

上面的问题是给 TLE (Time Limit Exceeds) 因为上面的问题是在 O(N^2) 时间复杂度中解决的。如问题中所述,算法应在 O(N) 时间内运行且不使用除法运算符。

方法一

public int[] productExceptSelf(int[] nums) {

    int[] leftProduct = new int[nums.length];
    int[] rightProduct = new int[nums.length];
    /**
      calculate the left Prefix and right Suffix Product.
    */
    for (int i=0,j= nums.length-1; i < nums.length; i++, j--) {
        if (i == 0) {
            leftProduct[i] = nums[i];
            rightProduct[j] = nums[j];
        }else {
            leftProduct[i] = leftProduct[i-1] * nums[i];
            rightProduct[j] = rightProduct[j+1] * nums[j];
        }
    }

    for (int i=0; i < nums.length; i++) {

        if (i == 0) {
            nums[i] = rightProduct[1];
        }else if (i == (nums.length - 1)) {
            nums[i] = leftProduct[i-1];
        }else {
            nums[i] = leftProduct[i-1] * rightProduct[i+1];
        }
    }
    return nums;
}

时间复杂度: O(N)空间复杂度: O(N)

这也可以在 O(1) 空间中解决(如前所述,输出数组不算作额外空间。)

提示:使用输出数组存储左边的 Prefix Product & 从右边遍历数组

于 2021-11-08T14:37:49.180 回答
0
class Solution {
    public int[] productExceptSelf(int[] arr) {
       int[]  res = new int[arr.length];
        for(int i =0, temp =1; i < arr.length;i++){ // first iteration to make res making temp inc
            res[i] = temp;
            temp *= arr[i];
           }
        for(int i = arr.length -1 , temp =1;i>=0;i--){
            res[i] *= temp;
            temp *= arr[i];
        }
        return res;
    }
}

**Time Complexity O(N) Space Complexity O(N)**
于 2021-11-27T05:42:36.507 回答