如何在 Java 中利用数组实现简单的前缀和(Prefix Sum)技术以支持 O(1) 时间的区间查询
如何在 Ja va 中利用数组实现简单的前缀和(Prefix Sum)技术以支持 O(1) 时间的区间查询

免费影视、动漫、音乐、游戏、小说资源长期稳定更新! 👉 点此立即查看 👈
在 Ja va 开发中,尤其是处理数据查询时,你是否遇到过这样的场景:需要频繁计算一个数组中某个连续区间的元素之和?如果每次都去遍历累加,效率显然不高。这时候,前缀和(Prefix Sum)技术就该登场了。它的核心思路非常巧妙:通过一次性的预处理,将后续所有区间求和的复杂度降至 O(1)。
构造前缀和数组
具体怎么实现呢?关键在于构建一个辅助数组。假设我们有一个原始数组 nums,长度为 n。通常,我们会选择构建一个长度为 n + 1 的“带哨兵”前缀和数组 prefix。这个小小的“+1”设计,能让我们在后续计算时省去不少边界判断的麻烦。
- 首先,初始化
prefix[0] = 0。 - 然后,从
i = 1开始遍历到n,执行prefix[i] = prefix[i - 1] + nums[i - 1]。
这样一来,prefix[i] 存储的值,就恰好是原数组 nums 中从第 0 个元素到第 i-1 个元素的总和。整个预处理过程只需要 O(n) 的时间。
实现 O(1) 区间查询
预处理完成后,真正的魔法就发生了。当我们需要查询原数组中任意闭区间 [left, right](其中 0 ≤ left ≤ right < n)的和时,只需要一个简单的减法:
sum = prefix[right + 1] - prefix[left]
这个公式为什么成立?我们拆解一下:
prefix[right + 1]代表了nums[0]到nums[right]的所有元素之和。prefix[left]代表了nums[0]到nums[left - 1]的所有元素之和。- 两者相减,中间重叠的部分被抵消,剩下的正是我们需要的
nums[left]到nums[right]的区间和。
看,一次查询,无论区间多长,都只需要常数时间,效率的提升立竿见影。
Ja va 示例代码
理论说清楚了,来看一个完整、可直接运行的 Ja va 示例代码,它会让你理解得更透彻:
public class PrefixSum { private int[] prefix;public PrefixSum(int[] nums) { int n = nums.length; prefix = new int[n + 1]; for (int i = 1; i <= n; i++) { prefix[i] = prefix[i - 1] + nums[i - 1]; } } // 查询 [left, right] 闭区间的和,O(1) public int rangeSum(int left, int right) { return prefix[right + 1] - prefix[left]; } // 使用示例 public static void main(String[] args) { int[] nums = {2, 1, 3, 5, 4}; PrefixSum ps = new PrefixSum(nums); System.out.println(ps.rangeSum(1, 3)); // nums[1]+nums[2]+nums[3] = 1+3+5 = 9 System.out.println(ps.rangeSum(0, 4)); // 全数组和 = 15 }}
注意事项与扩展
当然,前缀和技术并非万能钥匙。它最适合处理“静态数组”,也就是那些初始化后就不太会频繁修改元素值的场景。如果业务需求中需要支持大量的单点更新操作,那么前缀和每次更新都需要重新计算一大片,效率就不够看了。这时候,就该考虑更高级的数据结构,比如线段树或者树状数组(Fenwick Tree)。
最后,再划几个重点:
- 复杂度:空间复杂度为 O(n),预处理时间复杂度为 O(n),查询则是 O(1)。
- 边界检查:在实际生产代码中,务必记得在查询方法中加入索引越界的校验,例如判断
left和right是否在合法范围内,以及left是否小于等于right。- 思路延伸:这个一维前缀和的思路完全可以推广到二维,也就是“二维前缀和”,用于高效计算一个矩阵中任意子矩阵内所有元素的和,这在图像处理、动态规划等算法中非常有用。
游乐网为非赢利性网站,所展示的游戏/软件/文章内容均来自于互联网或第三方用户上传分享,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系youleyoucom@outlook.com。
同类文章
ubuntu cximage与其他软件比较
Ubuntu 下 CxImage 的定位与适用场景 在 Ubuntu 这类 Linux 系统中,当开发者需要在 C++ 应用中嵌入图像处理功能时,CxImage 常常会进入备选清单。它本质上是一个跨平台的 C++ 图像处理库,核心价值在于为应用程序提供轻量、易集成的图像编解码与基础处理能力。具体来说
VSCode插件市场版本管理_安装扩展的预览版与稳定版
VSCode扩展预览版安装与管理的完整指南 先说一个核心情况:VSCode默认的插件市场界面,只会给你展示稳定版扩展。那些带着“实验性”新功能的预览版(Beta或Alpha),其实就藏在后台,只是需要一点“特殊操作”才能调出来。这第一步,往往就把不少人给卡住了。 VSCode 怎么安装扩展的预览版(
ubuntu防火墙与其他安全工具对比
Ubuntu 防火墙与其他安全工具对比 一 核心概念与总体关系 在 Ubuntu 的生态里,防火墙配置这事儿,其实有清晰的层次。咱们先理清几个核心工具的关系: UFW (Uncomplicated Firewall):这是 Ubuntu 桌面和服务器上常见的“本地防火墙前端”。它的设计初衷很明确——
Node.js在Ubuntu上如何进行消息队列处理
在Ubuntu上使用Node js进行消息队列处理 想在Ubuntu上玩转消息队列?Node js生态提供了不少选择,比如RabbitMQ、Apache Kafka,还有Redis。今天,咱们就以RabbitMQ为例,手把手带你走一遍从安装到跑通第一个“Hello World”消息的全过程。 1
Ubuntu Node.js如何实现API接口开发
在Ubuntu上使用Node js实现API接口开发 想在Ubuntu系统上快速搭建一个API服务?Node js配合Express框架,可以说是开发者的黄金搭档。整个过程其实非常清晰,遵循一套标准的步骤就能让服务跑起来。下面,我们就来拆解一下这个流程。 1 安装Node js和npm 万事开头难
- 日榜
- 周榜
- 月榜
1
2
3
4
5
6
7
8
9
10
相关攻略
2015-03-10 11:25
2015-03-10 11:05
2021-08-04 13:30
2015-03-10 11:22
2015-03-10 12:39
2022-05-16 18:57
2025-05-23 13:43
2025-05-23 14:01
热门教程
- 游戏攻略
- 安卓教程
- 苹果教程
- 电脑教程
热门话题

