一、简介
1、前缀和是一个简单又好用的概念,它实际上采用了一个”记忆化“的思想。
2、通常,我们采用数组presum来保留前缀和的结果。presum[i]即nums数组从第0位置到第i位置的累加和。
3、前缀和的计算公式:presum[i]=presum[i-1]+nums[i]
4、但是为了防止越界,我们通常采用改进的版本。即把presum的长度定义为原数组长度+1。则presum[0]=0,相当于一个占位符。而presum[i]=presum[i-1]+nums[i-1]。(统一向前推进一位)
二、常见应用
1、求数组前i个数之和
直接返回presum[length]即可,不用重复计算
2、求数组的区间和
只用O(1)的时间,便可以快速求出nums在[i,j]上的和,公式如下:
sum(i,j)=presum[j+1]-presum[i]
三、例题
题目:
代码:
#include <iostream>
#include <vector>
#include <unordered_map>
class Solution {
public:
vector<int> subarraySum(vector<int>& nums) {
//答案数组
vector<int> res;
//定义哈希表,存储前缀和及首次出现的位置索引
//注意此处用map结构
//方便后面直接找到索引值
//因为无论是map还是set都是没有find函数可以直接定位索引值的
unordered_map<int, int> hash;
int len = nums.size();
int sum = 0;
hash[0] = 0;
for (int i = 1; i <= len; i++) {
sum += nums[i - 1];
if (hash.find(sum)!= hash.end()) {
int startIndex = hash[sum];
res.push_back(startIndex);
res.push_back(i - 1);
return res;
} else {
hash[sum] = i;
}
}
return res;
}
};
解析:见注释部分