除自身以外数组的乘积:简洁高效的算法
2023-09-17 11:49:33
引言
LeetCode 238:除自身以外数组的乘积是一个中等难度的算法问题,要求我们计算一个数组中每个元素的乘积,但不能包含元素本身。解决这一问题需要一个巧妙的算法,既能满足要求,又具有较高的效率。
思路
该算法的关键思想在于将数组的乘积拆分成两个部分:每个元素左边的乘积和右边的乘积。
具体来说,我们首先初始化两个数组:left
和 right
。left
数组存储每个元素左边所有元素的乘积,right
数组存储每个元素右边所有元素的乘积。
然后,我们从左到右遍历数组,计算 left
数组的每个元素。对于第一个元素,其左边没有元素,因此 left[0] = 1
。对于其他元素,left[i]
可以通过 left[i - 1] * nums[i - 1]
计算得出,其中 nums[i - 1]
是第 i-1
个元素。
接着,我们从右到左遍历数组,计算 right
数组的每个元素。与 left
数组类似,对于最后一个元素,其右边没有元素,因此 right[n - 1] = 1
。对于其他元素,right[i]
可以通过 right[i + 1] * nums[i + 1]
计算得出,其中 nums[i + 1]
是第 i+1
个元素。
最后,我们遍历数组,对于每个元素,其乘积可以简单地通过 left[i] * right[i]
计算得出。
示例
考虑数组 [1, 2, 3, 4]
。
-
计算
left
数组:left[0] = 1
left[1] = 1 * 1 = 1
left[2] = 1 * 1 * 2 = 2
left[3] = 2 * 1 * 2 = 4
-
计算
right
数组:right[3] = 1
right[2] = 1 * 4 = 4
right[1] = 4 * 3 = 12
right[0] = 12 * 2 = 24
-
计算乘积数组:
result[0] = left[0] * right[0] = 1 * 24 = 24
result[1] = left[1] * right[1] = 1 * 12 = 12
result[2] = left[2] * right[2] = 2 * 4 = 8
result[3] = left[3] * right[3] = 4 * 1 = 4
因此,给定数组 [1, 2, 3, 4]
,其乘积数组为 [24, 12, 8, 4]
。
复杂度分析
该算法的时间复杂度为 O(n),其中 n 是数组的长度。这是因为我们遍历了数组三次,每次遍历都花费 O(n) 的时间。
该算法的空间复杂度为 O(n),这是因为我们创建了两个额外的数组 left
和 right
,每个数组的大小都为 n。
结论
除自身以外数组的乘积问题是一个经典的算法问题,需要一个巧妙的解决方案。本文中提出的算法简洁高效,易于理解和实现。它使用分治的思想将数组的乘积拆分成两个部分,从而大幅降低了算法的复杂度。