625 字
3 分钟
算法 : 前缀和

§基础#

模板题:

class NumArray {
vector<int> s;
public:
NumArray(vector<int>& nums) {
s.resize(nums.size() + 1);
for(int i = 0; i < nums.size(); i++){
s[i + 1] = s[i] + nums[i];
}
}
int sumRange(int left, int right) {
return s[right + 1] - s[left];
}
};

§前缀和与哈希表#

class Solution {
public:
int subarraySum(vector<int>& nums, int k) {
int n = nums.size();
vector<int> s(n + 1);
for (int i = 0; i < n; i++) {
s[i + 1] = s[i] + nums[i];
}
unordered_map<int, int> cnt;
int ans = 0;
for (int sj : s) {
// 注意不要直接 += cnt[sj-k],如果 sj-k 不存在,会插入 sj-k
ans += cnt.contains(sj - k) ? cnt[sj - k] : 0;
cnt[sj]++;
}
return ans;
}
};

§距离和#

class Solution {
public:
vector<long long> minOperations(vector<int>& nums, vector<int>& queries) {
ranges::sort(nums);
int n = nums.size();
vector<long long> s(n + 1);
for(int i = 0; i < n; i++){
s[i + 1] = s[i] + nums[i];
}
int m = queries.size();
vector<long long> ans(m);
for(int i = 0; i < m; i++){
int q = queries[i];
long long j = ranges::lower_bound(nums,q) - nums.begin();
long long left = q * j - s[j];
long long right = s[n] - s[j] - q * (n - j) ;
ans[i] = left + right;
}
return ans;
}
};

§状态压缩前缀和#

§进阶#

§二维前缀和#

讲解

模板:

class NumMatrix {
vector<vector<int>> sum;
public:
NumMatrix(vector<vector<int>>& matrix) {
int m = matrix.size(), n = matrix[0].size();
sum.resize(m + 1, vector<int>(n + 1));
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
sum[i + 1][j + 1] = sum[i + 1][j] + sum[i][j + 1] - sum[i][j] + matrix[i][j];
}
}
}
// 返回左上角在 (r1, c1),右下角在 (r2, c2) 的子矩阵元素和
int sumRegion(int r1, int c1, int r2, int c2) {
return sum[r2 + 1][c2 + 1] - sum[r2 + 1][c1] - sum[r1][c2 + 1] + sum[r1][c1];
}
};
算法 : 前缀和
https://dingfengbo.vercel.app/posts/算法/前缀和/
作者
Eureka
发布于
2026-04-25
许可协议
CC BY-NC-SA 4.0