给你一个长度为 n 的整数数组 nums,其中 n > 1,返回输出数组 output ,其中 output[i] 等于 nums 中除 nums[i] 之外其余各元素的乘积。
示例:
1 | 输入: [1,2,3,4] |
提示:题目数据保证数组之中任意元素的全部前缀元素和后缀(甚至是整个数组)的乘积都在 32 位整数范围内。
说明: 请不要使用除法,且在 O(n) 时间复杂度内完成此题。
进阶:
你可以在常数空间复杂度内完成这个题目吗?( 出于对空间复杂度分析的目的,输出数组不被视为额外空间。)
方法一:暴力法
1 | class Solution { |
复杂度分析:时间复杂度为O(n^2),空间复杂度为O(1)。
方法二:统计0的个数
思路:设prod为数组nums中所有非零元素的乘积。统计数组nums中0的个数。
1.如果nums中没有0,则output[i] = prod / nums[i];
2.如果nums中有1个0,则
$$
output[i] =
\begin{cases}
prod, & 当 \mathrm{nums[i] = 0} \\
0, & 否则
\end{cases}
$$
3.如果nums中有2个(及以上)0,则数组output中所有元素全为0。
1 | class Solution { |
复杂度分析:时间复杂度为O(n),空间复杂度为O(1)。
该方法虽然时间复杂度达到了题目的要求,但使用了除法运算,违反了题目说明。
方法三:计算左右乘积
已知:
$$
output[i] = \underbrace{nums[0] \times nums[1] \times \cdots \times nums[i-1]} \times \underbrace{nums[i+1] \times \cdots \times nums[n-1]}
$$
如果先计算出左右两边的乘积:
$$
left[i] = nums[0] \times nums[1] \times \cdots \times nums[i-1] \\
right[i] = nums[i+1] \times \cdots \times nums[n-1]
$$
那么,$output[i] = left[i] \times right[i]$。
1 | class Solution { |
复杂度分析:时间复杂度为O(n),空间复杂度为O(n)。
方法四:原地求乘积
首先,按照从左到右的顺序,计算nums[i]左侧的乘积,并存储在output[i]中;
然后,按照从右到左的顺序,让output[i]再乘以nums[i]右侧乘积。
1 | class Solution { |
复杂度分析:时间复杂度为O(n),空间复杂度为O(1)。