238.除了自Leetcode之外的数组的乘积

问题描述 投票:0回答:7

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

给定一个整数数组 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
7个回答
9
投票

我也做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
投票

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

1
投票

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

方法-1

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) 空间中解决(正如提到的输出数组不计为额外空间。)

提示:使用输出数组存储左侧前缀积并从右侧遍历数组


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)**

0
投票
class Solution:
def productExceptSelf(self, nums: List[int]) -> List[int]:
    l=[]
    if nums.count(0)>=2:
        return [0]*len(nums)
    if nums.count(0)==1:
        index_of_zero=nums.index(0)
        k=nums
        s=1
        k.remove(0)
        for i in range(len(k)):
            s=s*k[i]
        l=[0]*len(k)
        l.insert(index_of_zero,s)
        return l
    else:
        s=1
        for i in range(len(nums)):
            s=s*nums[i]
        for i in range(len(nums)):
            l.append(s//nums[i])
        return l

0
投票

我最近收到这个问题。

这就是我在 Java8 中解决它的方法(绝对是在面试之后:p)。

private static List<Integer> getProduct(final int[] inputs) {
    int length = inputs.length;

    int[] prefixArr = new int[length];
    int[] suffixArr = new int[length];

    //leftArr
    prefixArr[0] = 1;
    //rightArr
    suffixArr[length - 1] = 1;

    for (int index = 1; index < length; index++)
        prefixArr[index] = inputs[index - 1] * prefixArr[index - 1];

    for (int index = (length - 2); index >= 0; index--)
        suffixArr[index] = inputs[index + 1] * suffixArr[index + 1];

    return IntStream
             .range(0, length)
             .mapToObj(index -> prefixArr[index] * suffixArr[index])
             .collect(Collectors.toList())
    ;
}

理想情况下,这可以在 2 个循环和一次流迭代中解决问题,因此满足 O(n)


0
投票

我使用python3来解决这个问题,我的代码非常有效,因为我首先计算了前缀和后缀的乘积,然后将两者结合起来。

class Solution:
def productExceptSelf(self, nums: List[int]) -> List[int]:

    n = len(nums)
    answer = [1] * n  
    prefix = 1
    for i in range(n):
        answer[i] = prefix 
        prefix *= nums[i]  
    

    suffix = 1
    for i in range(n - 1, -1, -1):
        answer[i] *= suffix
        suffix *= nums[i]  
    
    return answer
© www.soinside.com 2019 - 2024. All rights reserved.