题目描述
解法一:构造前、后缀乘积数组
class Solution(object):
def productExceptSelf(self, nums):
"""
:type nums: List[int]
:rtype: List[int]
"""
left = [1]+ [0]*(len(nums)-1) # 第一个元素左边没有元素,则前缀乘积记为 1
right = [0]*(len(nums)-1) + [1] # 最后一个元素右边没有元素,则后缀乘积记为 1
res = []
for i in range(1, len(nums)): # left[i] 为索引 i 左侧所有元素的乘积
left[i] = left[i-1]*nums[i-1]
for j in range(len(nums)-2, -1, -1): # right[j] 为索引 j 右侧所有元素的乘积
right[j] = right[j+1]*nums[j+1]
for k in range(len(nums)): # 除 nums[i] 之外其余各元素的乘积就是索引 i左侧所有元素的乘积乘以索引 i右侧所有元素的乘积
res.append(left[k]*right[k])
return res
时间复杂度:O(n),三轮for循环
空间复杂度:O(n),申请了两个额外数组 left和right
改进为空间复杂度 O(1)的方法
class Solution(object):
def productExceptSelf(self, nums):
"""
:type nums: List[int]
:rtype: List[int]
"""
res = [1]+[0]*(len(nums)-1) # res[i] 表示索引 i 左侧所有元素的乘积,第一个元素左边没有元素,所以 res[0]=1
for i in range(1, len(nums)):
res[i] = res[i-1]*nums[i-1]
# R 为右侧所有元素的乘积, 从后往前遍历,刚开始右边没有元素,所以 R = 1
R = 1
for i in range(len(nums)-1, -1, -1):
res[i] *= R # 对于索引 i的元素,左边所有元素的乘积为 answer[i],右边所有元素的乘积为 R
R *= nums[i] # R 需要包含右边所有的乘积,所以计算下一个结果时需要将当前值乘到 R 上
return res
解法二:构造乘积矩阵
class Solution(object):
def productExceptSelf(self, nums):
"""
:type nums: List[int]
:rtype: List[int]
"""
'''
nums = [1, 2, 3, 4]
nums[0] nums[1] nums[2] nums[3]
res[0] 1 2 3 4
res[1] 1 1 3 4
res[2] 1 2 1 4
res[3] 1 2 3 1
分别计算矩阵的上三角和下三角,并存储过程值。遍历两遍 nums即可得到结果
'''
res = [1]
bottom_mul = 1 # 下三角中的乘积过程值
top_mul = 1 # 上三角中的乘积过程值
# 计算下三角
for i in range(len(nums)-1): # 因为下三角中最大也不会取到 num最后一个元素,因此只遍历到 nums倒数第二个元素即可
bottom_mul *= nums[i]
res.append(bottom_mul)
# 计算上三角
for j in range(len(nums)-1, 0, -1): # 因为上三角中最小也不会取到 num第一个元素,因此从后往前遍历到 nums第二个元素即可
top_mul *= nums[j]
res[j-1] *= top_mul
return res
时间复杂度:O(n),两轮 for循环
空间复杂度:O(1),申请了两个变量 bottom_mul和 top_mul