除自身以外数组的乘积

题目描述

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

示例:

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

**提示:**题目数据保证数组之中任意元素的全部前缀元素和后缀(甚至是整个数组)的乘积都在 32 位整数范围内。

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

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

思路

首先需要排除掉求整个数组乘积再除以对应数的方法,当数组中有0时不可用。

思路一:

前缀和思路,维护left数组,表示前缀积,维护right数组,表示后缀积。

对于[1,2,3,4],left数组[1,1,2,6],right数组[24,12,4,1]

因此结果ans[i]=left[i]*right[i]

code

func productExceptSelf(nums []int) []int {
	ans, r := make([]int, len(nums)), make([]int, len(nums))
	ans[0] = 1
	for i := 1; i < len(ans); i++ {
		ans[i] = ans[i-1] * nums[i-1]
	}
	r[len(nums)-1] = 1
	for i := len(nums) - 2; i >= 0; i-- {
		r[i] = r[i+1] * nums[i+1]
	}
	for i := 0; i < len(nums)-1; i++ {
		ans[i] = ans[i] * r[i]
	}
	return ans
}

思路二:

思路一的left/right数组其中一个只需要使用一次,因此可以使用一个变量来保存即可

维护left数组,表示前缀积,维护变量r,表示后缀积,从后往前遍历,维护更新left数组和后缀积r

func productExceptSelf(nums []int) []int {
	ans := make([]int, len(nums))
	ans[0] = 1
	for i := 1; i < len(ans); i++ {
		ans[i] = ans[i-1] * nums[i-1]
	}
	r := nums[len(nums)-1]
	for i := len(ans) - 2; i >= 0; i-- {
		ans[i] = ans[i] * r
		r *= nums[i]
	}
	return ans
}