LC 238 - Product of Array Except Self
Question
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:
1
2
Input: nums = [1,2,3,4]
Output: [24,12,8,6]
Example 2:
1
2
Input: nums = [-1,1,0,-3,3]
Output: [0,0,9,0,0]
Constraints:
2 <= nums.length <= 105-30 <= nums[i] <= 30- The input is generated such that
answer[i]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.)
Links
Question here and solution here
Solution
concept
The main idea is to use prefix sum and suffix sum and calculate the product twice: front to back and back to front. One way to reduce space complexity is to store the values directly in the answer array. Take note that in the NeetSolution, the prefix sum start (index = 0) at 1, essentially the prefix sum array starts at index = 1 so it sort of lag behind the nums. This means that the prefix sum array at index = k does not contain nums[k]. This is the same for suffix sum although this array is not explicitly computed. As a result, when we do the product of prefix and suffix, the current index’s contribution is ignored.
code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
class Solution:
"""
my solution
prefix and suffix
"""
def productExceptSelf(self, nums: List[int]) -> List[int]:
prefix_sum = [nums[0]]
suffix_sum = [nums[-1]]
ans = []
for i in range(1, len(nums)):
prefix_sum.append(nums[i]*prefix_sum[-1])
for j in range(len(nums) - 2, -1, -1):
suffix_sum.append(nums[j]*suffix_sum[-1])
suffix_sum.reverse()
for k in range(0, len(nums)):
if k == 0:
ans.append(suffix_sum[1])
elif k == len(nums) - 1:
ans.append(prefix_sum[-2])
else:
ans.append(prefix_sum[k-1]*suffix_sum[k+1])
return ans
class NeetSolution(object):
def productExceptSelf(self, nums):
"""
:type nums: List[int]
:rtype: List[int]
space complexity: O(1)
time complexity: O(n)
went through the list twice, once from left to right, and once from right to left
from left to right: calculate product of all elements to the left of the current element -> prefix
from right to left: calculate product of all elements to the right of the current element -> postfix, then multiply it with the prefix
both prefix and post fix store at the same array, so the space complexity is O(1)
"""
ans = [1] * len(nums)
prefix = 1
for i in range(len(nums)):
ans[i] = prefix
prefix = prefix * nums[i]
postfix = 1
for i in range(len(nums)-1, -1, -1):
ans[i] = postfix * ans[i]
postfix = postfix * nums[i]
return ans
class NeetSolution:
def productExceptSelf(self, nums: List[int]) -> List[int]:
res = [1] * (len(nums))
for i in range(1, len(nums)):
res[i] = res[i-1] * nums[i-1]
postfix = 1
for i in range(len(nums) - 1, -1, -1):
res[i] *= postfix
postfix *= nums[i]
return res
Complexity
time: $O(n)$
space: $O(1)$