java
public class PrefixSum1D {
public static void main(String[] args) {
// 原始数组(下标从1开始,方便计算)
int[] nums = {0, 3, 1, 4, 1, 5, 9, 2, 6}; // 下标0不用,占位填0
int n = nums.length - 1; // 实际元素个数(去掉占位的0)
// ① 建立前缀和数组
int[] pre = new int[n + 1]; // pre[i] 表示 nums[1..i] 的总和
pre[0] = 0; // 前0个元素的和为0,这是边界
for (int i = 1; i <= n; i++) {
pre[i] = pre[i - 1] + nums[i]; // 当前前缀和 = 上一个前缀和 + 当前元素
}
// ② 查询区间 [l, r] 的和(下标从1开始)
// 公式:sum(l, r) = pre[r] - pre[l - 1]
int l = 2, r = 5;
int rangeSum = pre[r] - pre[l - 1];
// pre[5]=14, pre[1]=3, 所以区间[2,5]的和 = 14 - 3 = 11
System.out.println("区间[" + l + "," + r + "]的和 = " + rangeSum); // 11
}
}
总结一下
需要做的
1.初始化数据(需要开两个数组)
一个用来存数据(手动填数据,最前面填个0占位,开空间的话就用N+1,多开的1也是给占位0用的,否则会越界)
一个用来存前缀和(这个数组要开N+1,通常在for里面下标从1开始)
2.初始化左右边界值(相当于题目要求的区间范围)
看题目要求
例如:
int l = 2;
int r = 5;
2.核心解题公式
pre[i] = pre[i - 1] + nums[i];
在for里面执行,意思大概是:
当前前缀和 = 上一个前缀和 + 当前元素
int rangeSum = pre[r] - pre[l - 1];
无需在for中执行,意思大概是:
目标区间和 = 右边界前缀和 - 左边界上一位前缀和
重点!!!
pre[l-1]这里之所以要-1,是因为要确保左边界值不会被剪掉
反面例子,r=5,l=2,题目要求求[l,r] = [2,5]
如果不-1:
(1+2+3+4+5号的和) - (1+2号的和) = 3+4+5号的和
2号直接被吞掉了