16.除了自身以外数组乘积
给你一个整数数组 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]
方法1:两个数组left[i] 记录前 i 累乘;right[i] 记录后 i 个累乘。因此 ans[i] = left[i] * right[i] ;
left[0] = 1,right[0] = 1 初始化为1,方便记录left[1]=nums[1]
1 class Solution { 2 public int[] productExceptSelf(int[] nums) { 3 int length = nums.length; 4 5 // L 和 R 分别表示左右两侧的乘积列表 6 int[] L = new int[length]; 7 int[] R = new int[length]; 8 9 int[] answer = new int[length]; 10 11 // L[i] 为索引 i 左侧所有元素的乘积 12 // 对于索引为 '0' 的元素,因为左侧没有元素,所以 L[0] = 1 13 L[0] = 1; 14 for (int i = 1; i < length; i++) { 15 L[i] = nums[i - 1] * L[i - 1]; 16 } 17 18 // R[i] 为索引 i 右侧所有元素的乘积 19 // 对于索引为 'length-1' 的元素,因为右侧没有元素,所以 R[length-1] = 1 20 R[length - 1] = 1; 21 for (int i = length - 2; i >= 0; i--) { 22 R[i] = nums[i + 1] * R[i + 1]; 23 } 24 25 // 对于索引 i,除 nums[i] 之外其余各元素的乘积就是左侧所有元素的乘积乘以右侧所有元素的乘积 26 for (int i = 0; i < length; i++) { 27 answer[i] = L[i] * R[i]; 28 } 29 30 return answer; 31 } 32 } 33 34 作者:力扣官方题解
方法2: (方法1的升级版)
用ans[i]记录前 i 的累乘
直接再倒着遍历一遍,R 记录后 j 的累乘,ans[j] *= R
1 class Solution { 2 public int[] productExceptSelf(int[] nums) { 3 int length = nums.length; 4 int[] answer = new int[length]; 5 6 // answer[i] 表示索引 i 左侧所有元素的乘积 7 // 因为索引为 '0' 的元素左侧没有元素, 所以 answer[0] = 1 8 answer[0] = 1; 9 for (int i = 1; i < length; i++) { 10 answer[i] = nums[i - 1] * answer[i - 1]; 11 } 12 13 // R 为右侧所有元素的乘积 14 // 刚开始右边没有元素,所以 R = 1 15 int R = 1; 16 for (int i = length - 1; i >= 0; i--) { 17 // 对于索引 i,左边的乘积为 answer[i],右边的乘积为 R 18 answer[i] = answer[i] * R; 19 // R 需要包含右边所有的乘积,所以计算下一个结果时需要将当前值乘到 R 上 20 R *= nums[i]; 21 } 22 return answer; 23 } 24 } 25 26 // 作者:力扣官方题解

浙公网安备 33010602011771号