实现说明:
- 前缀和数组多预留1位(索引0初始化为0)便于区间计算
- 前缀乘积数组索引0初始化为1避免零值影响
- 查询方法将原始0-based索引转换为1-based处理
- 时间复杂度:预处理O(n),查询O(1)
注意点:
- 乘积查询需确保区间内不含0,否则需特殊处理
- 大数情况建议改用long类型防溢出
- 二维扩展可参考类似原理实现
public class PrefixUtils {
// 计算前缀和数组(索引从1开始)
public static int[] computePrefixSum(int[] nums) {
int[] prefixSum = new int[nums.length + 1];
for (int i = 1; i <= nums.length; i++) {
prefixSum[i] = prefixSum[i - 1] + nums[i - 1];
}
return prefixSum;
}
// 计算前缀乘积数组(索引从1开始)
public static int[] computePrefixProduct(int[] nums) {
int[] prefixProduct = new int[nums.length + 1];
prefixProduct[0] = 1; // 初始化为1避免乘积为0
for (int i = 1; i <= nums.length; i++) {
prefixProduct[i] = prefixProduct[i - 1] * nums[i - 1];
}
return prefixProduct;
}
// 查询区间和[left, right](闭区间,0-based)
public static int querySum(int[] prefixSum, int left, int right) {
return prefixSum[right + 1] - prefixSum[left];
}
// 查询区间乘积[left, right](闭区间,0-based)
public static int queryProduct(int[] prefixProduct, int left, int right) {
return prefixProduct[right + 1] / prefixProduct[left];
}
public static void main(String[] args) {
int[] testArr = {2, 3, 4, 5};
// 前缀和测试
int[] sumArr = computePrefixSum(testArr);
System.out.println("区间[1,3]的和: " + querySum(sumArr, 1, 3)); // 输出12
// 前缀乘积测试
int[] productArr = computePrefixProduct(testArr);
System.out.println("区间[0,2]的乘积: " + queryProduct(productArr, 0, 2)); // 输出24
}
}