给你一个整数数组 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 位整数范围内
进阶:
你可以在 O(1) 的额外空间复杂度内完成这个题目吗?( 出于对空间复杂度分析的目的,输出数组不被视为额外空间。)
Medium。
★★★★☆
这似乎是一个简单的问题,可以在线性时间和空间内解决。可以先计算给定数组所有元素的乘积,然后对数组中的每个元素 x,将乘积除以 x 求得除自身值以外的数组乘积。
然后这样的解决方法有一个问题,就是如果输入数组中出现 0,那么这个方法就失效了。而且在问题中说明了不允许使用除法运算。这增加了这个问题的难度。
遍历数组中的每一个元素,将当前元素之外的元素依次相乘,然后写到结果数组。
时间复杂度: O(n^2),需要两层遍历,第一层为遍历数组中的每一个元素,第二层是遍历数组中除当前元素的其他所有元素。
空间复杂度: O(1)。
注意:此方法不满足题目 O(n) 时间复杂度要求,且在 LeetCode 运行将「超出时间限制」。
下面以 Golang 为例给出实现。
func productExceptSelf(nums []int) []int {
products := make([]int, len(nums))
for i := range nums {
p := 1
for j, v := range nums {
if j != i {
p *= v
}
}
products[i] = p
}
return products
}
我们不必将所有数字的乘积除以给定索引处的数字得到相应的答案,而是可以利用索引处左侧的所有数字乘积和右侧所有数字的乘积相乘得到答案。
对于给定索引 i,我们将使用它左边所有数字的乘积乘以右边所有数字的乘积。
具体步骤如下:
时间复杂度:
O(n),其中 n 指的是数组 nums 的长度。预处理 L 和 R 数组以及最后的遍历计算都是 O(n) 的时间复杂度。
空间复杂度:
O(n),其中 n 指的是数组 nums 的长度。使用了 L 和 R 数组去构造答案,L 和 R 长度等于数组 nums。
下面以 Golang 为例给出实现。
func productExceptSelf(nums []int) []int {
n := len(nums)
L := make([]int, n)
R := make([]int, n)
// 构造左右乘积列表。
L[0] = 1
for i := 1; i < n; i++ {
L[i] = L[i-1] * nums[i-1]
}
R[n-1] = 1
for i := n - 2; i >= 0; i-- {
R[i] = R[i+1] * nums[i+1]
}
// 遍历数组,获取答案。
products := make([]int, n)
for i := range nums {
products[i] = L[i]*R[i]
}
return products
}
我们可以将上面方法的空间复杂度优化成 O(1)。
由于输出数组不算在空间复杂度内,那么我们可以将 L 或 R 数组用输出数组来计算。先把输出数组当作 L 数组来计算,然后再动态构造 R 数组得到结果。
具体步骤如下:
时间复杂度:
O(n),其中 n 指的是数组 nums 的长度。
空间复杂度:
O(1),输出数组不算进空间复杂度中,因此我们只需要常数的空间存放变量。
下面以 Golang 为例给出实现。
func productExceptSelf(nums []int) []int {
n := len(nums)
// 构造左乘积列表。
products := make([]int, n)
products[0] = 1
for i := 1; i < n; i++ {
products[i] = products[i-1] * nums[i-1]
}
// 遍历数组,获取答案。
R := 1
for i := n - 1; i >= 0; i-- {
products[i] = products[i] * R
R *= nums[i]
}
return products
}
238. 除自身以外数组的乘积 - LeetCode