product-of-array-except-self
function productExceptSelf(nums: number[]): number[] {
const n = nums.length;
const result = new Array(n).fill(1);
// 计算左侧乘积
let leftProduct = 1;
for (let i = 0; i < n; i++) {
result[i] *= leftProduct;
leftProduct *= nums[i];
}
// 计算右侧乘积并与左侧乘积相乘
let rightProduct = 1;
for (let i = n - 1; i >= 0; i--) {
result[i] *= rightProduct;
rightProduct *= nums[i];
}
return result;
}
时间复杂度:O(n),其中 n 是输入数组的长度。我们对数组进行了两次遍历。 空间复杂度:O(1),除了输出数组外,我们只使用了常数额外空间。
测试用例:
console.log(productExceptSelf([1, 2, 3, 4])); // 期望输出: [24,12,8,6]
console.log(productExceptSelf([-1, 1, 0, -3, 3])); // 期望输出: [0,0,9,0,0]
console.log(productExceptSelf([1, 1])); // 期望输出: [1,1]
console.log(productExceptSelf([0, 0])); // 期望输出: [0,0]
console.log(productExceptSelf([2, 3, 4, 5])); // 期望输出: [60,40,30,24]
这个解决方案巧妙地使用了数组的概念来解决问题,而没有使用除法操作:
- 我们首先创建一个结果数组,初始化为全 1。
- 然后,我们从左到右遍历输入数组,计算每个元素左侧所有数字的乘积,并存储在结果数组中。
- 接着,我们从右到左遍历输入数组,计算每个元素右侧所有数字的乘积,并与之前计算的左侧乘积相乘。
- 最终,结果数组中的每个元素就是除了自身以外其他所有元素的乘积。
这种方法避免了使用额外的存储空间来保存左侧和右侧的乘积,而是直接在结果数组上进行操作,从而达到了 O(1) 的额外空间复杂度。