[LeetCode] 238. Product of Array Except Self(数组除自身元素外的乘积)
-
Difficulty: Medium
-
Related Topics: Array
-
Link: https://leetcode.com/problems/product-of-array-except-self/
Description
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 elements of nums
except nums[i]
.
给一个数组 nums
(长度大于 1),返回一个数组 output
,其中 output[i]
等于 nums
数组内除 nums[i]
外所有元素的乘积。
Example
Input: [1,2,3,4]
Output: [24,12,8,6]
Constraint
It's guaranteed that the product of the elements of any prefix or suffix of the array (including the whold array) fits in a 32 bit integer.
输入保证数组的任何子数组的乘积结果都在 32 位整数范围内。
Note
Please solve it without division and in O(N).
请不使用除法并在 \(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.)
你能使用常数额外空间解答吗(用于输出的数组不计入空间复杂度分析)。
Solution
假设数组有 4 个元素 [a, b, c, d]
,那么最后的结果应该是 [bcd, acd, abd, abc]
,对于每个元素,我们以该元素为界,将其分为前半部分和后半部分,没有的部分用 1 填充,得到如下结果:
-
前半部分:
[1, a, ab, abc]
-
后半部分:
[bcd, cd, d, 1]
不难看出,分别做一次前缀积和一次后缀积,再将二者相乘,即可得到最终结果,代码如下:
class Solution {
fun productExceptSelf(nums: IntArray): IntArray {
// 前缀积
val prefix = IntArray(nums.size)
prefix[0] = 1
for (i in 1..nums.lastIndex) {
prefix[i] = nums[i - 1] * prefix[i - 1]
}
// 后缀积
val suffix = IntArray(nums.size)
suffix[nums.lastIndex] = 1
for (i in nums.lastIndex - 1 downTo 0) {
suffix[i] = nums[i + 1] * suffix[i + 1]
}
// 结果
val result = IntArray(nums.size)
for (i in nums.indices) {
result[i] = prefix[i] * suffix[i]
}
return result
}
}
至于 Follow up 里的常数额外空间,我在 discussion 里找了一下,大概思路就是只保留一个前缀积数组,后缀积则是边生成边乘上去,这样可以压缩掉两个额外数组空间,只有返回数组的空间了,代码如下:
class Solution {
fun productExceptSelf(nums: IntArray): IntArray {
val result = IntArray(nums.size)
result[0] = 1
for (i in 1..nums.lastIndex) {
result[i] = result[i - 1] * nums[i - 1]
}
var suffix = 1
for (i in nums.indices.reversed()) {
result[i] *= suffix
suffix *= nums[i]
}
return result
}
}