新生培训之 前缀和与差分 ----二维前缀和篇,docker快速使用yolov11。
·
二维前缀和的基本概念
二维前缀和是一种高效处理矩阵区间和查询的数据结构。通过预处理,可以在O(1)时间内计算任意矩形区域内的元素和。定义前缀和数组S,其中S[i][j]表示从(1,1)到(i,j)矩形区域内所有元素的和。
二维前缀和的构建方法
给定一个m×n的矩阵A,构建其前缀和数组S的过程如下: 初始化S[0][j]和S[i][0]为0。对于每个元素S[i][j],其值可以通过递推公式计算:
S[i][j] = S[i-1][j] + S[i][j-1] - S[i-1][j-1] + A[i][j]
这个公式通过容斥原理,避免了重复计算重叠区域的和。
区间和查询实现
要查询从(x1,y1)到(x2,y2)的矩形区域和,计算公式为:
sum = S[x2][y2] - S[x1-1][y2] - S[x2][y1-1] + S[x1-1][y1-1]
这个公式同样运用了容斥原理,先减去两个矩形区域的和,再加回被重复减去的部分。
代码实现示例
// 构建前缀和数组
vector<vector<int>> buildPrefixSum(const vector<vector<int>>& matrix) {
int m = matrix.size(), n = matrix[0].size();
vector<vector<int>> prefix(m+1, vector<int>(n+1, 0));
for (int i = 1; i <= m; ++i) {
for (int j = 1; j <= n; ++j) {
prefix[i][j] = prefix[i-1][j] + prefix[i][j-1] - prefix[i-1][j-1] + matrix[i-1][j-1];
}
}
return prefix;
}
// 查询矩形区域和
int querySum(const vector<vector<int>>& prefix, int x1, int y1, int x2, int y2) {
return prefix[x2][y2] - prefix[x1-1][y2] - prefix[x2][y1-1] + prefix[x1-1][y1-1];
}
典型应用场景
- 图像处理中的区域像素值统计
- 地理信息系统中的区域数据分析
- 动态规划中优化子矩阵计算
- 游戏开发中的碰撞检测优化
复杂度分析
构建前缀和数组的时间复杂度为O(mn),空间复杂度为O(mn)。每次查询的时间复杂度为O(1),这使得它特别适合需要频繁查询矩阵区域和的场景。
常见问题与优化
边界处理需要特别注意,确保下标不越界。对于非常大的矩阵,可以采用分块处理或压缩存储来优化空间。在实际应用中,可以根据需求将二维前缀和扩展到更高维度。
实战练习建议
- 实现基本的二维前缀和构建与查询
- 解决LeetCode上的相关题目(如304. 二维区域和检索 - 矩阵不可变)
- 尝试将二维前缀和应用于实际项目中的区域统计问题
- 比较不同实现方式的性能差异
更多推荐
所有评论(0)