Problem Description
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]
My Idea
My initial idea was to create the results list initiated with 1s. Then loop over nums and for each n create a list mult that has the value of n in every position except n’s index in nums and multiply this list with res. This, however, results in a time complexity of O(n^2). The better solution would be to reduce the amount of calculations by calculating the results of multiplying all the elements to the left and to the right of every index i respectively and multiply the results. This results in a time complexity of O(n). If done using two arrays it has a space complexity of O(n), but this can be reduced to O(1) if the calculations are done directly in res.
My solution
#Optimal solution with time complexity of O(n) and space complexity of O(1)
def productExceptSelf(nums: list[int]) -> list[int]:
l = len(nums)
res = [1] * l
left_product = 1
for i in range(l):
res[i] = left_product
left_product *= nums[i]
right_product = 1
for i in range(l - 1, -1, -1):
res[i] *= right_product
right_product *= nums[i]
return res
# Better solution with time and space complexity of O(n)
def productExceptSelfBetter(nums: list[int]) -> list[int]:
l=len(nums)
left = [1]*l
right = [1]*l
for i in range(1,l):
left[i]=left[i-1]*nums[i-1]
for i in range(l-2,-1,-1):
right[i]=right[i+1]*nums[i+1]
return [a*b for a,b in zip(left,right)]
# Initiial approach with time complexity O(n^2)
def productExceptSelfInitial(nums: list[int]) -> list[int]:
l=len(nums)
res=[1 for n in nums]
for i,e in enumerate(nums):
mult=[e]*l
mult[i]=1
res = [a*b for a,b in zip(res,mult)]
return res