【问题标题】:238.Product of Array Except Self-Leetcode238. 除了 Self-Leetcode 之外的数组的乘积
【发布时间】:2021-10-04 19:36:06
【问题描述】:

我一直在 leetcode 上尝试这个问题。 238.Product of array except self

给定一个整数数组nums,返回一个数组答案,使得 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.

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

【问题讨论】:

    标签: java arrays prefix-sum


    【解决方案1】:

    我也做 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;
    }
    

    【讨论】:

    • 我看到解决方案非常好!谢谢!
    【解决方案2】:

    上面的问题是给 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 并从右边遍历数组

    【讨论】:

      【解决方案3】:

      这个解决方案也给出了 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;
      }
      

      【讨论】:

      • 锐化解决方案
      【解决方案4】:
      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)**
      

      【讨论】:

      • 感谢您的回答,也是您的第一个!然而,该代码在逻辑上似乎等同于@Vishen 之前提供的答案。在 StackOverflow 上,通常不包括此类重复的答案。也许最好删除这个答案,而是在 StackOverflow 上寻找一个还没有答案的问题?
      猜你喜欢
      • 2022-01-03
      • 2020-04-20
      • 1970-01-01
      • 2021-04-11
      • 1970-01-01
      • 2018-02-22
      • 2015-08-03
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多