一、基本概念
定义:前缀和数组(Prefix Sum Array)是一个数组,它存储了原数组(或序列)的连续子数组之和。对于一个给定的数组 nums
,其前缀和数组 cumulativeSum
的第 i
个元素 cumulativeSum[i]
表示 nums
从第一个元素到第 i
个元素的累加和。
表示累加和:前缀和数组的计算公式可以表示为:
cumulativeSum[i] = cumulativeSum[i - 1] + nums[i - 1]
其中, cumulativeSum[0]
通常初始化为 0,以便于计算。
二、构造方法
初始化:在构造前缀和数组时,首先需要创建一个长度比原数组 nums
多一个元素的新数组 cumulativeSum
。这样做是为了简化边界条件的处理,特别是当需要计算从第一个元素开始的子区间和时。
遍历更新:通过遍历原数组 nums
,我们可以逐个计算前缀和数组的元素。这个过程可以表示为一个循环,从 i = 1
遍历到 nums.length
,每次更新 cumulativeSum[i]
的值为 cumulativeSum[i - 1]
加上 nums[i - 1]
。
三、查询操作
快速计算:给定一个闭区间 [left, right]
,我们可以通过以下公式快速计算该区间的累加和:
sum = cumulativeSum[end + 1] - cumulativeSum[start]
这里,end+ 1
是为了包含 end
索引的元素在内,因为前缀和数组的索引是从 1 开始的。
时间复杂度:查询操作的时间复杂度是 O(1),因为一旦前缀和数组被构造出来,任何区间和的查询都可以直接通过数组索引完成,无需再次遍历原数组。
四、应用场景
区间查询:在处理需要频繁查询区间和的问题时,前缀和数组非常有用。例如,在一个数据流应用中,你可能需要快速回答“到目前为止,总共有多少数据量?”前缀和数组可以立即给出答案。
动态规划:在动态规划问题中,前缀和数组可以用来优化状态转移,特别是在涉及到区间和计算的问题,如最长递增子序列、最小子树和等。
五、优化和变种
优化技巧:在某些情况下,我们可以优化前缀和数组的构造过程。例如,如果原数组是有序的,我们可以利用二分查找来加速更新过程。
变种:前缀和数组的概念可以扩展到多维。例如,在二维数组中,我们可以构造一个二维前缀和数组,用于快速计算矩形区域的和(后续内容)。
六、代码实现
public class CumulativeSumCalculator {
// 累积和数组
private int[] cumulativeSum;
// 初始化累积和数组
public CumulativeSumCalculator(int[] nums) {
// 初始化累积和数组,第一个元素为0
cumulativeSum = new int[nums.length + 1];
// 计算累积和
for (int index = 1; index <= nums.length; index++) {
cumulativeSum[index] = cumulativeSum[index - 1] + inputArray[index - 1];
}
}
// 查询指定区间的累积和
public int querySum(int start, int end) {
// 返回区间 [start, end] 的累积和
return cumulativeSum[end + 1] - cumulativeSum[start];
}
}