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; }};§距离和
- 2602. 使数组元素全部相等的最少操作次数(前缀和+二分查找+排序)
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]; }};