Algorithm/src/main/java/array/ProductExceptSelf.java

66 lines
2.9 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package array;
/**
* 题目238. 除自身以外数组的乘积 (productExceptSelf)
* 描述:给你一个整数数组 nums返回 数组 answer ,其中 answer[i] 等于 nums 中除 nums[i] 之外其余各元素的乘积 。
* 题目数据 保证 数组 nums之中任意元素的全部前缀元素和后缀的乘积都在 32 位 整数范围内。
* 请 不要使用除法,且在 O(n) 时间复杂度内完成此题。
* 链接https://leetcode.cn/problems/product-of-array-except-self/
*
示例 1:
输入: nums = [1,2,3,4]
输出: [24,12,8,6]
示例 2:
输入: nums = [-1,1,0,-3,3]
输出: [0,0,9,0,0]
*/
//没做出来
//二刷不会
public class ProductExceptSelf {
/**
* 用一个数组 left 存储当前位置左侧所有元素的乘积left[0]=1每往右一步就把前一步的乘积乘上前一步的元素。
* 用一个数组 right 存储当前位置右侧所有元素的乘积right[n-1]=1每往左一步就把后一步的乘积乘上后一步的元素。
* 最终结果 res[i] = left[i] * right[i],既含括了除自身以外的所有元素。
* 这样只需两次线性遍历,时间 O(n),不使用除法;若要 O(1) 额外空间,可把前缀积直接存到结果数组,再用一个变量累积后缀积。
* @param nums
* @return
*/
public int[] productExceptSelf(int[] nums) {
int size = nums.length; // 数组长度
if (size == 0) // 如果输入数组为空
return new int[]{}; // 返回空数组
int[] left = new int[size], // left[i] 存 nums[0..i-1] 的乘积
right = new int[size]; // right[i] 存 nums[i+1..n-1] 的乘积
left[0] = 1; // 第一个元素左侧没有元素,乘积为 1
right[size - 1] = 1; // 最后一个元素右侧没有元素,乘积为 1
// 计算所有前缀积
for (int i = 1; i < size; i++) {
// left[i] = left[i-1] * nums[i-1]
// 即当前位置左侧乘积 = 前一个左侧乘积 × 前一个元素
left[i] = left[i - 1] * nums[i - 1];
}
// 计算所有后缀积
for (int j = size - 2; j >= 0; j--) {
// right[j] = right[j+1] * nums[j+1]
// 即当前位置右侧乘积 = 后一个右侧乘积 × 后一个元素
right[j] = right[j + 1] * nums[j + 1];
}
int[] res = new int[size]; // 用于存放最终结果
// 合并前缀积和后缀积
for (int k = 0; k < size; k++) {
// 排除自身的所有元素乘积 = left[k] × right[k]
res[k] = left[k] * right[k];
}
return res; // 返回结果数组
}
}