Nameless Site

But one day, you will stand before its decrepit gate,without really knowing why.

0%

除自身以外数组的乘积

来自Leetcode第238题除自身以外数组的乘积

给定长度为 n 的整数数组 nums,其中 n > 1,返回输出数组 output ,其中 output[i] 等于 nums 中除 nums[i] 之外其余各元素的乘积。

示例:

1
2
输入: [1,2,3,4]
输出: [24,12,8,6]

说明:不要使用除法,且在 O(n) 时间复杂度内完成此题。

进阶:
你可以在常数空间复杂度内完成这个题目吗?( 出于对空间复杂度分析的目的,输出数组不被视为额外空间。)


这似乎是一个简单的问题,可以在线性时间和空间内解决。可以先计算给定数组所有元素的乘积,然后对数组中的每个元素 x,将乘积除以 x* 来求得除自身值的以外的数组乘积。

然后这样的解决方法有一个问题,就是如果输入数组中出现 0,那么这个方法就失效了。而且在问题中说明了不允许使用除法运算。这增加了这个问题的难度。

  1. 初始化数组长度n。初始化res=[0,0,…,0]为1\n的数组。初试化乘积k=1
  2. 从左向右遍历,遍历区间[0,n):
    • res每个位置保存它左侧所有元素的乘积。即res[i]=k,k∗=nums[i]
  3. 重置乘积k=1,用来保存元素右边的乘积和
  4. 从右向左遍历,遍历区间(n,0]:
    • res[i]∗=k,表示将当前位置的左积乘以右积。
    • 更新右积k∗=nums[i]
  5. 返回res
1
2
3
4
5
6
7
8
9
10
11
12
13
14
public int[] productExceptSelf(int[] nums) {
int[] ans = new int[nums.length];
int tmp = 1;
for(int i = 0 ; i < ans.length ; i++){
ans[i] = tmp;
tmp *= nums[i]; // 此时数组存储的是除去当前元素左边的元素乘积
}
tmp = 1;
for(int i = ans.length - 1;i >= 0 ; i--){
ans[i] *= tmp; // tmp为该数右边的乘积。
tmp *= nums[i]; // 此时数组等于左边的 * 该数右边的
}
return ans;
}