给你一个整数数组 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]
提示:
2 <= nums.length <= 105-30 <= nums[i] <= 30- 保证 数组
nums之中任意元素的全部前缀元素和后缀的乘积都在 32 位 整数范围内
进阶:你可以在 O(1) 的额外空间复杂度内完成这个题目吗?( 出于对空间复杂度分析的目的,输出数组 不被视为 额外空间。)
题解:
/**
* @description: 双数组 TC:O(n) SC:O(n)
* @author: JunLiangWang
* @param {*} nums 给定数组
* @return {*}
*/
function twoArray(nums) {
/**
* 本方案采用双数组的方式,定义左右两数组leftArray,rightArray长度与
* nums一致。
*
* 对于两数组索引i处元素:
*
* 左数组i处元素leftArray[i]为nums的[0至i-1]的乘积
* 右数组i处元素rightArray[i]为nums的[i+1,nums.length-1]的乘积
*
* 除 nums[i] 之外其余各元素的乘积则为:leftArray[i]*rightArray[i]
*
* 示例: nums = [1,2,3,4]
* leftArray = [1,1,2,6]
* rightArray= [24,12,4,1]
* 结果= [24,12,8,6]
*/
//定义左右两数组leftArray,rightArray长度与nums一致。
let leftArray = new Array(nums.length),
rightArray = new Array(nums.length),
outArray = new Array(nums.length);
// 初始化左数组[0]为1
leftArray[0] = 1;
// 初始化右数组最后一个元素为1
rightArray[nums.length - 1] = 1;
let index = 0;
// 遍历计算左数组元素值:
// 左数组i处元素leftArray[i]为nums的[0至i-1]的乘积
while (index < nums.length - 1) {
leftArray[index + 1] = leftArray[index] * nums[index]
index++;
}
// 遍历计算右数组元素值:
// 右数组i处元素rightArray[i]为nums的[i+1,nums.length-1]的乘积
index = nums.length - 1;
while (index > 0) {
rightArray[index - 1] = rightArray[index] * nums[index]
index--;
}
// 遍历计算结果:
// 除 nums[i] 之外其余各元素的乘积则为:leftArray[i]*rightArray[i]
index = 0;
while (index < nums.length) {
outArray[index] = leftArray[index] * rightArray[index]
index++;
}
// 返回结果
return outArray;
}
/**
* @description: 单数组 TC:O(n) SC:O(1)
* @author: JunLiangWang
* @param {*} nums 给定数组
* @return {*}
*/
function singleArray(nums) {
/**
* 我们可以对上述方案进行优化,使用一个数组即可完成
*/
//定义结果数组长度与nums一致。
let outArray = new Array(nums.length);
// 初始化数组[0]为1
outArray[0] = 1;
// 遍历计算左数组元素值:
// 左数组i处元素outArray[i]为nums的[0至i-1]的乘积
let index = 0;
while (index < nums.length - 1) {
outArray[index + 1] = outArray[index] * nums[index]
index++;
}
index = nums.length - 1;
// 定义变量记录nums的[i+1,nums.length-1]的乘积
let rightResult = 1;
// 遍历计算右数组元素值并直接计算结果
while (index >= 0) {
// 除 nums[i] 之外其余各元素的乘积则为:outArray[i]*rightResult
outArray[index] *= rightResult
//更新nums的[i+1,nums.length-1]的乘积
rightResult *= nums[index]
index--;
}
// 返回结果
return outArray
}
来源:力扣(LeetCode)