前缀和算法

embedded/2025/3/18 5:36:14/

前缀和算法 是一种通过预处理数组,快速计算任意区间和的技巧。它能在 O(1) 时间复杂度内回答区间和的查询,适用于需要频繁计算子数组/子区间和的问题。以下是其核心应用场景、实现方法及经典例题:


一、适用场景

  1. 频繁查询区间和
    • 多次计算数组的某一子区间 [L, R] 的和。
  2. 统计满足条件的子数组数量
    • 例如“和为k的子数组数量”、“和为偶数的子数组数量”等。
  3. 处理环形数组或二维矩阵
    • 环形数组通过复制数组处理,二维矩阵扩展为二维前缀和。
  4. 结合哈希表优化查找
    • 寻找满足 preSum[j] - preSum[i] = target 的索引组合。

二、实现步骤

  1. 预处理前缀和数组
    • 定义 preSum[i] 表示数组前 i 项的和(索引通常从1开始)。
    • 递推公式:preSum[i] = preSum[i-1] + nums[i-1]
  2. 计算区间和
    • 区间 [L, R] 的和为 preSum[R+1] - preSum[L](左闭右闭区间)。
  3. 结合哈希表优化
    • 遍历时记录前缀和出现次数,快速统计满足条件的子数组。

三、经典例题与代码

1. 一维前缀和(区间和查询)
class PrefixSum:def __init__(self, nums):n = len(nums)self.preSum = [0] * (n + 1)for i in range(1, n+1):self.preSum[i] = self.preSum[i-1] + nums[i-1]def query(self, L, R):  # 闭区间 [L, R]return self.preSum[R+1] - self.preSum[L]# 示例
nums = [1, 2, 3, 4]
ps = PrefixSum(nums)
print(ps.query(1, 2))  # 输出 2+3=5
2. 统计和为k的子数组数量(哈希优化)
def subarraySum(nums, k):preSum = {0: 1}  # 初始前缀和为0出现1次current_sum = 0count = 0for num in nums:current_sum += num# 若 current_sum - target 存在,则存在子数组和为kcount += preSum.get(current_sum - k, 0)preSum[current_sum] = preSum.get(current_sum, 0) + 1return count# 示例
nums = [1, 1, 1]
print(subarraySum(nums, 2))  # 输出 2
3. 二维前缀和(矩阵区域和)
class MatrixPrefixSum:def __init__(self, matrix):m, n = len(matrix), len(matrix[0])self.preSum = [[0]*(n+1) for _ in range(m+1)]for i in range(1, m+1):for j in range(1, n+1):self.preSum[i][j] = matrix[i-1][j-1] + self.preSum[i-1][j] + self.preSum[i][j-1] - self.preSum[i-1][j-1]def query(self, x1, y1, x2, y2):  # 左上角(x1,y1),右下角(x2,y2)return self.preSum[x2+1][y2+1] - self.preSum[x1][y2+1] - self.preSum[x2+1][y1] + self.preSum[x1][y1]# 示例
matrix = [[1, 2, 3],[4, 5, 6],[7, 8, 9]
]
mps = MatrixPrefixSum(matrix)
print(mps.query(1, 1, 2, 2))  # 输出 5+6+8+9=28

四、常见问题与陷阱

  1. 索引偏移问题
    • 前缀和数组通常比原数组多一个元素,需注意索引转换(例如原数组的 nums[i] 对应 preSum[i+1])。
  2. 负数与哈希表结合
    • 当数组中存在负数时,前缀和可能重复,需用哈希表记录所有出现位置。
  3. 环形数组处理
    • 若数组是环形的(如 LeetCode 918),可将原数组复制一份拼接,转化为线性问题。

五、适用问题特征

  • 题目中出现 “子数组和”“连续区间和”“多次查询区间和” 等关键词。
  • 暴力解法时间复杂度为 O(n²),前缀和可优化至 O(n)O(1)

前缀和是解决子数组/子区间问题的利器,结合哈希表或二分查找可进一步扩展其应用场景。


http://www.ppmy.cn/embedded/173503.html

相关文章

2000-2023年各地级市二氧化碳排放量数据/地级市CO2排放量

2000-2023年各地级市二氧化碳排放量数据/地级市CO2排放量 1、时间:2000-2023年 2、来源:EDGAR_2024_GHG of October 2024 3、指标:年份、省份、城市、城市代码、所属地域、CO2排放总量_吨 4、范围:300个地级市 5、指标解释&a…

【芯片验证】面试题·对深度为60的数组进行复杂约束的技巧

朋友发给我的芯片验证笔试题,觉得很有意思,和大家分享一下。 面试题目 class A中一个长度为60的随机数组rand int arr[60],如何写约束使得: 1.每个元素的值都在(0,100]之间,且互不相等; 2.最少有三个元素满足勾股数要求,比如数组中包含3,4,5三个点; 请以解约束最快…

嵌入式八股RTOS与Linux---前言篇

前言 Linux与RTOS是校招八股的时候很喜欢考察的知识,在这里并没有把两个操作系统完全的独立开去讲,放在一起对比或许可能加深印象。我们讲Linux的内核有五部分组成:进程调度、内存管理、文件系统、网络接口、进程间通信,所以我也将从这五方面出发 中断管理去对比和RTOS的不同。…

渗透测试工具之Koadic

1. Koadic 简介 Koadic 是一款专为 Windows 网络 设计的 渗透测试 和 内部漏洞测试 工具。开发者将其描述为一个 命令与控制(C2)后渗透(Post-Exploitation)Rootkit,它利用 Windows Script Host(WSH) 或 VBScript 模块 进行攻击。Koadic 兼容 Windows 2000 至 Windows 1…

案例驱动的 IT 团队管理:创新与突破之路:第一章 重构 IT 团队管理:从传统到创新-1.1.1技术迭代加速与人才断层

👉 点击关注不迷路 👉 点击关注不迷路 👉 点击关注不迷路 文章大纲 案例驱动的 IT 团队管理:创新与突破之路第一章 重构 IT 团队管理:从传统到创新-1.1.1 技术迭代加速与人才断层1. 技术迭代加速的现状与影响1.1 技术迭…

mysql学习-常用sql语句

1、安装mysql参考网上链接,进入mysql数据库 mysql -u root -p 2、数据库操作 2.1、创建数据库 create database 数据库名 default character set utf8; 2.2、显示所有数据库 show databases; 2.3、选择数据库 use elementInfo; 2.4、删除数据库 drop database…

LORA: LOW-RANK ADAPTATION OF LARGE LANGUAGE MODELS 论文阅读

一、TL;DR 为什么要这么做?预训练模型越来越大,比如GPT-3 175B训练独立变得越来越不可行方法:冻结预训练模型的权重,在Transformer架构的每一层中注入可训练的低秩分解矩阵效果:训练参数量减少10000x&…

【实战ES】实战 Elasticsearch:快速上手与深度实践-附录-1-常用命令速查表-集群健康检查、索引生命周期管理、故障诊断命令

👉 点击关注不迷路 👉 点击关注不迷路 👉 点击关注不迷路 附录-常用命令速查表 1-Elasticsearch 运维命令速查表(集群健康检查、ILM管理、故障诊断)一、集群健康检查与监控1.1 集群健康状态核心命令1.2 节点级健康诊断…