当前位置: 首页 > news >正文

万户网站天下企业咨询方案

万户网站天下,企业咨询方案,wordpress最佳速度优化,西安seo顾问培训文章目录 一、一维前缀和​1. 基本概念​2. C 代码实现​3. 应用场景​ 二、二维前缀和1. 基本概念​2. C 代码实现​3. 应用场景​ 三、总结​ 在算法竞赛和日常的数据处理工作中,前缀和是一种极其重要的预处理技术。它能够在常数时间内回答多次区间查询&#xff0…

文章目录

  • 一、一维前缀和​
    • 1. 基本概念​
    • 2. C++ 代码实现​
    • 3. 应用场景​
  • 二、二维前缀和
    • 1. 基本概念​
    • 2. C++ 代码实现​
    • 3. 应用场景​
  • 三、总结​

在算法竞赛和日常的数据处理工作中,前缀和是一种极其重要的预处理技术。它能够在常数时间内回答多次区间查询,大大提高了算法效率。对于刚接触算法的新手来说,前缀和可能有些抽象,但只要掌握其核心思想和推导过程,就能轻松驾驭。接下来,本文将详细介绍一维前缀和和二维前缀和的原理、推导、实现以及应用场景。​

一、一维前缀和​

1. 基本概念​

一维前缀和的核心思想,是通过记录数组前 i 个元素的累加和,来快速计算数组中任意区间的和。我们以一个简单的数组 arr = [1, 3, 5, 7, 9] 为例,来详细推导前缀和数组的构建过程。​
前缀和数组 s 的定义为:​

  • s[0] = arr[0],在我们的例子中,s[0] = 1,即前缀和数组的第一个元素等于原数组的第一个元素。​
  • i > 0时,s[i] = s[i - 1] + arr[i]。比如计算s[1],根据公式,s[1] = s[0] + arr[1],已知s[0] = 1arr[1] = 3,所以s[1] = 1 + 3 = 4 ;继续计算s[2],s[2] = s[1] + arr[2] = 4 + 5 = 9;以此类推,完整的前缀和数组 s[1, 4, 9, 16, 25]。​

通过前缀和数组,我们就可以快速计算原数组中任意区间[i, j]的和。当i > 0时,区间和为s[j] - s[i - 1],这是因为s[j]包含了从arr[0]arr[j]的所有元素和,而s[i - 1]包含了从arr[0]arr[i - 1]的所有元素和,两者相减,就得到了arr[i]arr[j]的元素和;当i == 0时,区间和直接是s[j],因为此时前缀和数组s[j]就是从原数组开头到arr[j]的所有元素和。​

2. C++ 代码实现​

下面是一维前缀和数组的 C++ 实现代码:

#include <iostream>
#include <vector>
using namespace std;// 计算一维前缀和数组
vector<int> calculatePrefixSum(const vector<int>& arr) {int n = arr.size();if (n == 0) return {};vector<int> prefixSum(n);prefixSum[0] = arr[0];for (int i = 1; i < n; ++i) {prefixSum[i] = prefixSum[i - 1] + arr[i];}return prefixSum;
}// 查询区间[i, j]的和
int queryRangeSum(const vector<int>& prefixSum, int i, int j) {if (i == 0) {return prefixSum[j];} else {return prefixSum[j] - prefixSum[i - 1];}
}int main() {// 示例数组vector<int> arr = {1, 3, 5, 7, 9};// 计算前缀和数组vector<int> prefixSum = calculatePrefixSum(arr);// 查询区间[1, 3]的和(对应原数组的第2到第4个元素)int sum = queryRangeSum(prefixSum, 1, 3);cout << "区间[1, 3]的和为: " << sum << endl; // 输出结果应为3 + 5 + 7 = 15return 0;
}

calculatePrefixSum 函数中,首先处理原数组为空的情况,然后初始化前缀和数组的第一个元素为原数组第一个元素,接着通过循环,根据前缀和公式依次计算出前缀和数组的其他元素。queryRangeSum函数则根据区间起始位置 i 是否为 0,选择不同的计算方式来返回区间和。

3. 应用场景​

一维前缀和的常见应用场景包括:​

  • 频繁查询数组任意区间的和。例如在一个记录每天销售额的数组中,需要频繁查询某段时间内的总销售额,使用一维前缀和就能快速得出结果。​
  • 快速计算数组子数组的和,用于解决子数组和相关问题。比如在一些算法题目中,要求找出和满足特定条件的子数组,前缀和可以帮助我们高效地计算子数组的和,从而快速筛选出符合条件的子数组。​
  • 在统计和数据处理中,快速计算累积数据。如统计学生成绩的累计分数,通过前缀和可以快速得到每个学生及其之前学生的总成绩。

二、二维前缀和

1. 基本概念​

二维前缀和数组是一维前缀和在二维空间上的扩展,常用于快速计算二维数组中任意子矩阵的和。为了便于理解,我们以一个 3×3 的二维数组 matrix 为例进行推导,假设matrix为:

[[1, 2, 3],[4, 5, 6],[7, 8, 9]
]

二维前缀和数组 s 的定义为:s[i][j] 表示从原矩阵左上角 (0, 0) 到右下角 (i, j) 所构成的子矩阵中所有元素的和。​

其递推公式的推导过程如下:​

i > 0j > 0时,s[i][j] = matrix[i][j] + s[i - 1][j] + s[i][j - 1] - s[i - 1][j - 1]。我们来分析这个公式,matrix[i][j] 是当前位置的元素;s[i - 1][j] 表示的是从左上角 (0, 0)(i - 1, j) 的子矩阵和,它包含了当前位置左边所有元素的和;s[i][j - 1] 表示从左上角 (0, 0)(i, j - 1) 的子矩阵和,它包含了当前位置上边所有元素的和;而 s[i - 1][j - 1]s[i - 1][j]s[i][j - 1] 中都被计算了一次,即左上角 (0, 0)(i - 1, j - 1) 的子矩阵和被重复计算了,所以要减去一次 s[i - 1][j - 1],这样就能得到从左上角 (0, 0) 到右下角 (i, j) 的子矩阵和。​
对于边界情况,当 i == 0j > 0 时,s[0][j] = s[0][j - 1] + matrix[0][j],因为第一行没有上面的子矩阵,所以前缀和就是前一个位置的前缀和加上当前位置的元素;当 j == 0i > 0 时,s[i][0] = s[i - 1][0] + matrix[i][0],同理,第一列没有左边的子矩阵,前缀和是前一个位置的前缀和加上当前位置的元素;当 i == 0j == 0 时,s[0][0] = matrix[0][0]

通过二维前缀和数组,我们可以在 O (1) 时间内计算出原矩阵中任意子矩阵 [(x1, y1), (x2, y2)] 的和。计算公式为:当 x1 > 0y1 > 0 时,sum = s[x2][y2] - s[x1 - 1][y2] - s[x2][y1 - 1] + s[x1 - 1][y1 - 1]。这个公式的原理和递推公式类似,s[x2][y2] 是包含目标子矩阵的大矩阵和,s[x1 - 1][y2]s[x2][y1 - 1] 分别减去了目标子矩阵左边和上边多余的部分,但这样会导致左上角的子矩阵被多减了一次,所以要加上s[x1 - 1][y1 - 1] ;当x1 == 0y1 == 0 时,按照类似的边界情况处理方式进行计算。

2. C++ 代码实现​

下面是二维前缀和数组的 C++ 实现代码:

#include <iostream>
#include <vector>
using namespace std;// 计算二维前缀和数组
vector<vector<int>> calculatePrefixSum2D(const vector<vector<int>>& matrix) {int rows = matrix.size();if (rows == 0) return {};int cols = matrix[0].size();vector<vector<int>> prefixSum(rows, vector<int>(cols, 0));// 初始化前缀和数组的第一行和第一列prefixSum[0][0] = matrix[0][0];// 初始化第一行for (int j = 1; j < cols; ++j) {prefixSum[0][j] = prefixSum[0][j - 1] + matrix[0][j];}// 初始化第一列for (int i = 1; i < rows; ++i) {prefixSum[i][0] = prefixSum[i - 1][0] + matrix[i][0];}// 填充剩余的前缀和数组for (int i = 1; i < rows; ++i) {for (int j = 1; j < cols; ++j) {prefixSum[i][j] = matrix[i][j] + prefixSum[i - 1][j] + prefixSum[i][j - 1] - prefixSum[i - 1][j - 1];}}return prefixSum;
}// 查询子矩阵[(x1, y1), (x2, y2)]的和(闭区间,包含四个端点)
int querySubmatrixSum(const vector<vector<int>>& prefixSum, int x1, int y1, int x2, int y2) {if (x1 == 0 && y1 == 0) {return prefixSum[x2][y2];} else if (x1 == 0) {return prefixSum[x2][y2] - prefixSum[x2][y1 - 1];} else if (y1 == 0) {return prefixSum[x2][y2] - prefixSum[x1 - 1][y2];} else {return prefixSum[x2][y2] - prefixSum[x1 - 1][y2] - prefixSum[x2][y1 - 1] + prefixSum[x1 - 1][y1 - 1];}
}int main() {// 示例二维数组vector<vector<int>> matrix = {{1, 2, 3},{4, 5, 6},{7, 8, 9}};// 计算二维前缀和数组vector<vector<int>> prefixSum = calculatePrefixSum2D(matrix);// 查询子矩阵[(1, 1), (2, 2)]的和(对应原矩阵的右下角2x2子矩阵)int sum = querySubmatrixSum(prefixSum, 1, 1, 2, 2);cout << "子矩阵[(1, 1), (2, 2)]的和为: " << sum << endl; // 输出结果应为5 + 6 + 8 + 9 = 28return 0;
}

calculatePrefixSum2D 函数中,先处理二维数组为空的情况,然后初始化二维前缀和数组,接着分别初始化第一行和第一列,最后通过两层循环,根据二维前缀和的递推公式填充整个前缀和数组。querySubmatrixSum 函数则根据子矩阵的起始位置是否在边界,选择不同的计算方式返回子矩阵的和。​

3. 应用场景​

二维前缀和的常见应用场景包括:​

  • 频繁查询二维数组中任意子矩阵的和。比如在图像像素处理中,可能需要频繁计算图像中某个区域的像素总和,使用二维前缀和就能快速完成计算。​
  • 图像处理中的区域像素和计算。除了求和,基于前缀和还可以计算区域的平均像素值等统计信息,为图像分析提供基础数据。​
  • 地理信息系统中的区域统计分析。在地理信息系统中,将地图数据以二维数组形式存储,使用二维前缀和可以快速计算某个区域内的各种统计数据,如人口总数、土地面积总和等。​

三、总结​

前缀和是一种非常实用的预处理技术,通过构建前缀和数组,可以将区间和查询的时间复杂度从 O (n)O (n²) 降低到 O (1),大大提高了算法效率。无论是一维前缀和还是二维前缀和,理解其推导过程是掌握这项技术的关键。对于新手来说,建议多通过实际例子和练习题来加深对前缀和的理解和应用。希望本文对你理解前缀和算法有所帮助!如果你有任何疑问或建议,欢迎在评论区留言讨论。

http://www.15wanjia.com/news/158740.html

相关文章:

  • 外国高端网站设计广西seo关键词怎么优化
  • 公司做网站需要网站维护人员吗上海网站建设小程序
  • 国外网站怎么做网站后门怎么去除
  • 网站开发工资多少钱一个月响应式网站视频
  • 厦门外贸网站建设多少钱新网站优化
  • 东莞做企业营销型网站的公司龙华网站建设设计
  • 国外网站模板欣赏烟台市建设工程质量监督站网站
  • 长春市住房建设局网站wordpress怎样对接dz
  • 典型网站建设做那个网站大全
  • 长治网站建设公司app设计报价
  • 建设银行网站短信错误6次网站做有偿广告需要什么有序
  • 岳西县住房和城乡建设局网站前端开发工程师工资
  • 建设网站的安全措施网站基本建设的原理
  • 西安网站建设市场优化整站
  • 制作网站复杂吗开源镜像网站开发
  • 大型餐饮网站建设关键词优化易下拉稳定
  • 如何创建自己的公司网站小白怎么做无货源电商
  • 可以做软件的网站有哪些内容微信支付 公司网站
  • 北苑做网站的公司网页设计 效果图
  • 欧洲购物网站排名国外优秀ps网站
  • 广州网站开发学校南京建设网页制作
  • 提升了自己的网站网站开发怎么找客户
  • 成都市企业网站建设jsp手机版网站开发
  • 网站建设留言板闵行建设机械网站
  • 一个专门做各种恐怖片的电影网站昆明网页设计培训学校
  • 简单企业网站源码安卓app开发需要学什么
  • 做网站有必要做app吗视频聚合网站怎么做不侵权
  • 免费的网站模板下载北京高端购物商场
  • 做网站有什么要求怎么做海淘网站
  • 北京一个公司做网站认证网站域名空间5个G的多少钱