[LeetCode Hot100] 除自身以外数组的乘积|左右乘积列表,Java实现!图解+代码,小白也能秒懂!
✏️本文对应题目链接:除自身以外数组的乘积
给你一个整数数组 nums
,返回数组 answer
,其中 answer[i]
等于 nums
中除 nums[i]
之外其余各元素的乘积。
题目数据保证数组之中任意元素的全部前缀元素和后缀的乘积都在 32 位整数范围内。
请不要使用除法,且在 O(n) 时间复杂度内完成此题。
示例:
输入:nums = [1,2,3,4]
输出:[24,12,8,6]
如何在O(n)时间复杂度内,不使用除法,计算每个元素除自身以外的乘积?
关键步骤:
left
和 right
,分别存储每个元素左侧和右侧的乘积answer[i] = left[i] * right[i]
输入数组:
nums = [1, 2, 3, 4]
步骤1:计算左侧乘积
left[0] = 1
left[1] = 1 * 1 = 1
left[2] = 1 * 2 = 2
left[3] = 2 * 3 = 6
left = [1, 1, 2, 6]
步骤2:计算右侧乘积
right[3] = 1
right[2] = 1 * 4 = 4
right[1] = 4 * 3 = 12
right[0] = 12 * 2 = 24
right = [24, 12, 4, 1]
步骤3:计算结果
answer[0] = left[0] * right[0] = 1 * 24 = 24
answer[1] = left[1] * right[1] = 1 * 12 = 12
answer[2] = left[2] * right[2] = 2 * 4 = 8
answer[3] = left[3] * right[3] = 6 * 1 = 6
answer = [24, 12, 8, 6]
class Solution {
public int[] productExceptSelf(int[] nums) {
int n = nums.length;
int[] answer = new int[n];
// 计算左侧乘积
int[] left = new int[n];
left[0] = 1;
for (int i = 1; i < n; i++) {
left[i] = left[i - 1] * nums[i - 1];
}
// 计算右侧乘积
int[] right = new int[n];
right[n - 1] = 1;
for (int i = n - 2; i >= 0; i--) {
right[i] = right[i + 1] * nums[i + 1];
}
// 计算结果
for (int i = 0; i < n; i++) {
answer[i] = left[i] * right[i];
}
return answer;
}
}
left
和 right
关键思路:用输出数组 answer
代替左侧乘积列表,使用变量动态计算右侧乘积。
class Solution {
public int[] productExceptSelf(int[] nums) {
int n = nums.length;
int[] answer = new int[n];
// 计算左侧乘积
answer[0] = 1;
for (int i = 1; i < n; i++) {
answer[i] = answer[i - 1] * nums[i - 1];
}
// 计算右侧乘积并更新结果
int right = 1;
for (int i = n - 1; i >= 0; i--) {
answer[i] = answer[i] * right;
right = right * nums[i];
}
return answer;
}
}
✅ 左右乘积核心思想:将问题分解为左侧乘积和右侧乘积
✅ 空间优化技巧:用输出数组代替额外空间
✅ 适用场景:数组累积问题、前缀后缀问题