题目描述
给你一个整数数组 nums
,返回 数组 answer
,其中 answer[i]
等于 nums
中除 nums[i]
之外其余各元素的乘积 。
题目数据 保证 数组 nums
之中任意元素的全部前缀元素和后缀的乘积都在 32 位 整数范围内。
请 不要使用除法,且在 O(n)
时间复杂度内完成此题。
示例 1:
输入: nums = [1,2,3,4]
输出: [24,12,8,6]
示例 2:
输入: nums = [-1,1,0,-3,3]
输出: [0,0,9,0,0]
提示:
2 <= nums.length <= 105
-30 <= nums[i] <= 30
- 保证 数组
nums
之中任意元素的全部前缀元素和后缀的乘积都在 32 位 整数范围内
代码及注释
func productExceptSelf(nums []int) []int {
length := len(nums)
res := make([]int, length)
// 计算每个元素左侧所有元素的乘积
res[0] = 1
for i := 1; i < length; i++ {
res[i] = res[i - 1] * nums[i - 1]
}
// 计算每个元素右侧所有元素的乘积,并与左侧乘积相乘
num := 1
for i := length - 1; i >= 0; i-- {
res[i] *= num
num *= nums[i]
}
return res
}
代码解释
-
左侧乘积计算:
- 创建一个数组
res
来存储每个元素的左侧所有元素的乘积。 - 初始化
res[0] = 1
。 - 使用循环计算每个元素的左侧所有元素的乘积,并存储在
res
数组中。
- 创建一个数组
-
右侧乘积计算:
- 使用一个变量
num
来存储每个元素右侧所有元素的乘积。 - 从数组的最后一个元素开始,更新
res[i]
为res[i] * num
,然后更新num
为num * nums[i]
。
- 使用一个变量
示例:
假设 nums = [1, 2, 3, 4]
:
-
计算左侧乘积:
res = [1, 1*1, 1*1*2, 1*1*2*3] = [1, 1, 2, 6]
-
计算右侧乘积并与左侧乘积相乘:
- 从右到左,
num
初始为1
。- 对于
nums[3] = 4
:res[3] = 6 * 1 = 6
,num = 4 * 1 = 4
。 - 对于
nums[2] = 3
:res[2] = 2 * 4 = 8
,num = 3 * 4 = 12
。 - 对于
nums[1] = 2
:res[1] = 1 * 12 = 12
,num = 2 * 12 = 24
。 - 对于
nums[0] = 1
:res[0] = 1 * 24 = 24
。
- 对于
- 从右到左,
时间复杂度分析:
- 首先,计算左侧乘积的时间复杂度是 O(n)。
- 然后,计算右侧乘积并与左侧乘积相乘的时间复杂度同样是 O(n)。
因此,总的时间复杂度是 O(n)。