Home Leetcode

238. Product of Array Except Self

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].

Constraints:

The most finicky constraint is the ban on the division operator—otherwise, the solution would be very simple: simply calculate the product of the entire array, and for every answer[i], we calculate product / nums[i]. Without division, however, we must build the answers from scratch.

A naïve solution would be to calculate nums[0] * ... * nums[i - 1] * nums[i + 1] * ... * nums[len(nums) - 1] for every index i individually, giving us a runtime complexity in O(n2)\mathcal{O}(n^2).

However, we can consider a few facts:

We can therefore use the recurrence relations of pip_i and sis_i to calculate the prefixes and the suffixes through a forward pass and a backward pass respectively.

PRODUCT-EXCEPT-SELF(nums: int array):
	initialise result array with 1s
	
	// calculate prefixes and store them in the array
	prefix = 1
	for i = 0, ..., l - 1:
		result[i] = prefix
		prefix = prefix * nums[i]
	// calculate suffixes and obtain answer
	suffix = 1
	for i = l - 1, ..., 0:
		result[i] = result[i] * suffix  // result = prefix[i] * suffix[i]
		suffix = nums[i] * suffix
	
	return result array

Notice that we can store the prefixes in the array itself to save space, since that doesn’t affect the calculation of the suffixes—that only depends on the previous suffix, and nums!

def productExceptSelf(self, nums: List[int]) -> List[int]:
	res = [1] * (len(nums))
	
	prefix = 1
	for i in range(len(nums)):
		res[i] = prefix
		prefix *= nums[i]
	suffix = 1
	for i in range(len(nums) - 1, -1, -1):
		res[i] *= suffix
		suffix *= nums[i]
	
	return res

Time Complexity

We have two for loops in the algorithm: the forward pass to calculate prefixes, and the backward pass to calculate the suffixes and the answer. Each iteration of both are constant, since it is only two multiplication operations. Therefore, the runtime complexity is in O(n)\mathcal{O}(n).

Space Complexity

We don’t count the output array in space complexity analysis. The other variables used are constant, since we only store the latest prefix/suffix—thus, the space complexity is constant, in O(1)\mathcal{O}(1).