给你一个长度为 n 的整数数组 nums,其中 n > 1,返回输出数组 output ,其中 output[i] 等于 nums 中除 nums[i] 之外其余各元素的乘积。
示例:
输入: [1,2,3,4]
输出: [24,12,8,6]
提示:题目数据保证数组之中任意元素的全部前缀元素和后缀(甚至是整个数组)的乘积都在 32 位整数范围内。
说明: 请不要使用除法,且在 O(n) 时间复杂度内完成此题。
进阶:
你可以在常数空间复杂度内完成这个题目吗?( 出于对空间复杂度分析的目的,输出数组不被视为额外空间。)
思路:
题目本身比较好理解,就是在除了该位置外,把这个数组中其余的元素全部乘起来就可以了。
这个题目提示用到前缀和后缀,这个时候就可以考虑用这个方法去解题。每个位置的结果就是用这个位置左边所有元素的乘积*右边所有元素的乘积。所有关键的问题是怎么去找左右两边元素的乘积。这个时候可以声明一个列表用前缀和的方法去做。这个列表保存的是每个位置左边所有元素之积。那么左边之积有了,就差右边了,此时可以有两种方法去解决:①和左边元素一样在声明一个列表去保存右边所有元素之积,这样空间复杂度会变成O(n);②为了简化空间复杂度,我们可以设置一个变量,这个变量在每次循环遍历列表的时候不断的去更新右边元素之积。这样空间复杂度就降低为O(1)。接下来代码示例一下:
class Solution:
def productExceptSelf(self, nums: List[int]) -> List[int]:
#声明列表长度
length = len(nums)
#初始左侧前缀积的数组
answer = [0]*length
# answer[i] 表示索引 i 左侧所有元素的乘积
# 因为索引为 '0' 的元素左侧没有元素, 所以 answer[0] = 1
answer[0] = 1
for i in range(1, length):
answer[i] = nums[i - 1] * answer[i - 1]
print(answer) # [1, 1, 2, 6]
# R 为右侧所有元素的乘积
# 刚开始右边没有元素,所以 R = 1
R = 1
for i in range(length-1,-1,-1):
# 对于索引 i,左边的乘积为 answer[i],右边的乘积为 R
answer[i] = answer[i] * R
# R 需要包含右边所有的乘积,所以计算下一个结果时需要将当前值乘到 R 上
R *= nums[i]
return answer
画图展示: