Problem
Given an array nums of n integers where n > 1, return an array output such that output[i] is equal to the product of all the elements of nums except nums[i].
Example:
Input: [1,2,3,4]
Output: [24,12,8,6]
Note: Please solve it without division and in O(n).
Follow up:
Could you solve it with constant space complexity? (The output array does not count as extra space for the purpose of space complexity analysis.)
解题思路
如果题目中允许我们使用除法,那么最简单的方式就是先将所有的数据累乘起来,再遍历整个数组,用累乘的结果去处以当前遍历到的数据即可得到结果,题目中有严格要求不可以使用除法,那么我们只能另找出路。
这道题的思路其实很简单,我们可以首先定义两个数组, l e f t left left和 r i g h t right right,长度和原数组一致, l e f t left left用来保存从左向右的每一步的累乘结果, r i g h t right right用来保存从右向左的每一步的累乘结果,然后在从头开始遍历,将当前数据左侧的累乘结果和右侧的累乘结果相乘即可,需要注意的是第一个元素和最后一个元素的特殊情况,第一个元素没有左侧累乘结果,所以直接赋予右侧的累乘结果,最后一个元素没有右侧的累乘结果,因此直接赋予左侧的累乘结果。
代码如下:
class Solution:
def productExceptSelf(self, nums: list) -> list:
left = [None for i in range(len(nums))]
l = 1
for i in range(len(nums)):
left[i] = l * nums[i]
l = l * nums[i]
right = [None for i in range(len(nums))]
r = 1
for i in reversed(range(len(nums))):
right[i] = r * nums[i]
r = r * nums[i]
ans = [None for i in range(len(nums))]
# 两个特殊情况
ans[0] = right[1]
ans[-1] = left[-2]
for i in range(1, len(nums) - 1):
ans[i] = left[i - 1] * right[i + 1]
return ans
接着题目提出了一个问题,能不能使用常数级别的空间解决问题(不包括最后的返回结果的数组)。通过分析,可以发现,我们上面的代码定义了3个和原数组相同大小的数组,除去最后的结果数组外,空间复杂度是 O ( 2 N ) O(2N) O(2N), N N N表示的是数组的长度。通过分析,发现是可以对空间复杂度进行一定的优化的,在求右侧的累乘结果时,保存了很多用不到的数据,也就是说我们在求得累乘结果时,这些结果用一次就被保存下来,浪费空间,因此,我们可以对这一部分空间进行优化。用一个变量保存右侧的累乘结果,而不是用一个数组去保存。同理,左侧的累乘结果也是一样的,我们只需要开辟和数组等长的空间来保存左侧的累乘结果即可,在左侧累乘结果的基础上从后向前遍历,每一步求得右侧的累乘结果,然后和左侧的相乘即可。
代码如下:
class Solution:
def productExceptSelf(self, nums: list) -> list:
ans = [None for i in range(len(nums))]
l = 1
for i in range(len(nums)):
ans[i] = l
l = l * nums[i]
r = 1
for i in reversed(range(len(nums))):
ans[i] = ans[i] * r
r = r * nums[i]
return ans
上述的代码只是用了两个变量去遍历数据,因此是常数级别的空间。