Product of Array Except Self - LeetCode

https://leetcode.com/problems/product-of-array-except-self/description/?envType=study-plan-v2&envId=top-interview-150

LeetCode_Sharing.png

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

The product of any prefix or suffix of nums is guaranteed to fit in a 32-bit integer.

You must write an algorithm that runs in O(n) time and without using the division operation.

Example 1:

Input: nums = [1,2,3,4]
Output: [24,12,8,6]

Example 2:

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

Constraints:

  • 2 <= nums.length <= 105
  • 30 <= nums[i] <= 30
  • The product of any prefix or suffix of nums is guaranteed to fit in a 32-bit integer.

Follow up: Can you solve the problem in O(1) extra space complexity? (The output array does not count as extra space for space complexity analysis.)

解析

将所有非零元素乘积计算出来,除每一个位置的元素即可。

class Solution:
    def productExceptSelf(self, nums: List[int]) -> List[int]:
        product = 1
        zeroCnt = 0
        result = []
        for num in nums:
            if num != 0:
                product *= num
            else:
                zeroCnt += 1
        for i in nums:
            if zeroCnt > 1:
                return [0] * len(nums)
            if zeroCnt == 1:
                if i != 0:
                    result.append(0)
                else:
                    result.append(product)
            else:
                result.append(product//i)
        
        return result

题目要求不使用除法

一个简单的方法是使用左和右两个数组来保存某个索引之前和之后所有数字的乘积。

  • left[i] 代表 nums[0]nums[i-1] 的乘积。
  • right[i] 代表 nums[i+1]nums[n-1] 的乘积。

那么除了 nums[i] 外数组的乘积就是 left[i]right[i] 的乘积。

为了满足O(1)的空间复杂度,我们可以不使用额外的两个数组来保存乘积,而是在输出数组上直接构造前缀和后缀。

class Solution:
    def productExceptSelf(self, nums: List[int]) -> List[int]:
        n = len(nums)
        
        # 输出数组,初始化为1
        ans = [1] * n
        
        # 构造左边乘积
        left = 1
        for i in range(1, n):
            left = left * nums[i - 1]
            ans[i] *= left
        
        # 构造右边乘积
        right = 1
        for i in range(n-2, -1, -1):
            right = right * nums[i + 1]
            ans[i] *= right
        
        return ans
class Solution {
    public int[] productExceptSelf(int[] nums) {
        int n = nums.length;
        int[] ans = new int[n];

        for (int i = 0; i < n; i++) {
            ans[i] = 1;
        }
        int left = 1;
        for (int i = 1; i < n; i++) {
            left = left * nums[i - 1];
            ans[i] *= left;
        }
        int right = 1;
        for (int i = n - 2; i >= 0; i--) {
            right *= nums[i + 1];
            ans[i] *= right;
        }
        return ans;
    }
}
class Solution {
public:
    vector<int> productExceptSelf(vector<int>& nums) {
    int n = nums.size();
    vector<int> ans(n, 1);
    int left = 1;
    for (int i = 1; i < n; ++i) {
        left *= nums[i - 1];
        ans[i] *= left;
    }
    int right = 1;
    for (int i = n - 2; i > -1; --i) {
        right *= nums[i + 1];
        ans[i] *= right;
    }
    return ans;
    }
};