给你一个整数数组 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.初始化变量:
-n 为输入数组 nums 的长度。
- 创建两个辅助数组 s1 和 s2,大小均为 n + 10,这里预留一定的空间以避免越界(实际存储时不会用到末尾的额外空间)。
- 将 s1[0] 设置为 1,表示乘积开始的基数;将 s2[n + 1] 设置为 1,作为递归求解过程中的结束条件。
2.遍历数组 nums,分别计算前缀积和后缀积: - 对于前缀积 s1,从第二个元素开始,将当前元素与前一个元素的积存入数组对应位置。
- 对于后缀积 s2,从倒数第二个元素开始向前遍历,同样将当前元素与下一个元素的积存入数组对应位置。
3.计算结果数组 ans - 遍历数组 nums,对于每个索引 i,计算该位置的结果值为 s1[i - 1] * s2[i + 1],即当前位置的前缀积与后一位的后缀积相乘。
4.返回结果数组 ans。
class Solution {
// 定义一个方法 productExceptSelf,输入参数为整数数组 nums,返回值类型为 int[],表示除自身外所有元素的乘积数组
public int[] productExceptSelf(int[] nums) {
// 获取输入数组 nums 的长度
int n = nums.length;
// 初始化两个辅助数组 s1 和 s2,用于存储前缀积和后缀积
int[] s1 = new int[n + 10], s2 = new int[n + 10];
// 设置前缀积数组 s1 的初始值:s1[0] 表示没有元素时的乘积,初始化为 1
s1[0] = 1;
// 设置后缀积数组 s2 的末尾值:s2[n + 1] 作为计算过程中的边界条件,初始化为 1
s2[n + 1] = 1;
// 计算前缀积数组 s1
for (int i = 1; i <= n; i++) {
// 将当前元素与前一个元素的乘积存入 s1[i]
s1[i] = s1[i - 1] * nums[i - 1];
}
// 计算后缀积数组 s2(从后往前遍历)
for (int i = n; i >= 1; i--) {
// 将当前元素与下一个元素的乘积存入 s2[i]
s2[i] = s2[i + 1] * nums[i - 1];
}
// 初始化结果数组 ans,用于存放除自身外所有元素的乘积
int[] ans = new int[n];
// 计算并填充结果数组 ans
for (int i = 1; i <= n; i++) {
// 当前索引 i 对应的结果值为 s1[i - 1] 与 s2[i + 1] 的乘积
ans[i - 1] = s1[i - 1] * s2[i + 1];
}
// 返回最终计算得到的结果数组 ans
return ans;
}
}