文章目录
一、前缀和的用途
运用前缀和的思想,可以在索引区间内更有效率地求出元素和。使用前缀和可以有效地避免for循环反复调用从而减少sumrange方法的调用频率,降低sumrange的时间复杂度,提高整个程序的运行效率。
二、算法运用
1.一维数组计算和
下面选用力扣的303. 区域和检索 - 数组不可变练习,详情请读者自动跳转至原题。
该题解题思路在于先算出各个连续的元素和,用减法去算区间内的和,相比一个个数相加,其时间复杂度降为O(1),提高了算法效率。
以下为图解:
代码如下(示例):
class NumArray {
private int[] presum;//构建数组
public NumArray(int[] nums) {
presum=new int[nums.length+1];
for(int i=1;i<presum.length;i++)
{
presum[i]=presum[i-1]+nums[i-1];//计算数组累加和
}
}
//查询目标区间内的和
public int sumRange(int left, int right) {
return presum[right+1]-presum[left];
}
}
2.二维矩阵计算和
下面选用力扣的304. 二维区域和检索 - 矩阵不可变练习,详情请读者自动跳转至原题。
该题的解题思路在于先计算出所有类型矩阵的元素和,再找到合适的大矩阵去加减小矩阵算出目标值,矩阵内的元素和计算没有难度,关键在于找到一个共同的顶点,便于各个矩阵的计算。
以下为图解:
代码如下(示例):
class NumMatrix {
private int[][] presum;//存储各矩阵元素和
public NumMatrix(int[][] matrix) {
int m=matrix.length,n=matrix[0].length;
if(m==0||n==0) return;
presum =new int[m+1][n+1];//构造前缀和矩阵
for(int i=1;i<=m;i++){
for(int j=1;j<=n;j++){
presum[i][j]=presum[i-1][j] +presum[i][j-1]+matrix[i-1][j-1]-presum[i-1][j-1];//计算[0,0]~[i,j]各矩阵元素和
}
}
}
//计算目标矩阵元素之和
public int sumRegion(int row1, int col1, int row2, int col2) {
return presum[row2+1][col2+1]-presum[row1][col2+1]-presum[row2+1][col1]+presum[row1][col1];
}
}
3.统计子数组数量
下面选用力扣的560. 和为 K 的子数组练习,详情请读者自动跳转至原题。
该题解题思路类似于一维数组,其不同点在于在前缀和中找与K互补的值,也运用到哈希表去映射前缀和出现的次数,提高算法效率。
以下为图解:
代码如下(示例):
class Solution {
public int subarraySum(int[] nums, int k) {
int n=nums.length;
int[] presum=new int[n+1];//存储前缀和
HashMap<Integer,Integer> count =new HashMap<>();//当前前缀和出现次数的映射
count.put(0,1);//记录下标为0的第一个前缀和0出现1次
int m=0;//记录和为k的子数组数量
for(int i=1;i<=n;i++){
presum[i]=presum[i-1]+nums[i-1];//计算前缀和
int target=presum[i]-k;//逆向思维寻找条件值
if(count.containsKey(target)){//查询目标值是否在哈希表中
m+=1;
}
//将当前前缀和存入哈希表
if(!count.containsKey(presum[i])){
count.put(presum[i],1);//记录该数第一次出现
}
else count.put(presum[i],count.get(presum[i])+1);//记录该数多次出现
}
return m;
}
}
总结
一维数组:先算各区间的和,利用区间和算出目标值
二维数组:找到一个共同的顶点(从目标矩阵的四个顶点中找到最合适的一个),以顶点向四周矩形状发散,通过大矩形加减内部小矩形的方式算出目标区域的元素和
子数组的数量查找:类似于一维数组先进行前缀和的存储,然后根据题意利用已算好的前缀和去找到目标值,其难点在于利用哈希表去存储前缀和并映射出其出现的次数,方便查找