刷题总结——区间和

hayden's blog / 2025-02-21 / 原文

前缀和

前缀和是一种解决区间求和问题的辅助方法,前缀和只适用于固定区间(数组、树等),如果区间元素发生变化,则不适用,此时需要考虑树状数组、线段树等方式。

问题类型

常见的问题也是和DP一样,求最大/最小/方案数。

类型 题目 备注
前缀和+哈希 LC 560 两数之和 思路
前缀和+二分 LC 2389 利用前缀和数组单调非递减
距离和 LC 2602 数学计算
异或前缀和 LC 1310 求的是异或前缀和,表示异或结果
二维前缀和 LC 304 表示以某个元素坐标为对角线的矩形
树前缀和 LC 437 利用hash

思考

  • 前缀和通常留一个presum[0]的特例,用来避免特殊情况的判断。
  • 区分正整数子序列问题(无顺序要求,可以排序之后求前缀和进行划分)和子数组(连续,只能使用滑动窗口划分),如2389
    • 前缀和与子数组的关系:前缀和本身就是一个子数组(从0开始),前缀和之差也是一个子数组
    • 前缀和与子序列的关系:前缀和表示了一个特定子序列的和
  • 正整数前缀和数组往往是单调非递减的,可以使用二分来优化
  • 一种瞬间检查所有子数组和的方法(two sum思路): 对每个前缀使用hash检查,并且把前缀加到hash中,这种方式可以在一次遍历过程中添加
  • 注意与DP的联系:一些用前缀和求最大子数组/子序列的问题涉及到如何选择下标,可以使用前缀和解决,如LC 53和LC 221

差分

差分数组指的是数组中每个值后减前作差得到的结果
性质:

  • 差分数组,从左至右累加O(n),可以得到原始数组对应位置的值。
  • 对于连续子数组所有元素的操作,等于对差分数组中连续子数组左右区间端点的操作(因为对于连续子数组内部,差分不变)
    • 利用这个性质,可以实现O(1)时间的区间操作,即区间操作转换成2个单点操作
    • 结合上一性质,可以方便地复原出原始数组
      类比:
  • 差分数组:微分
  • 前缀和:积分

题目

考虑上下车问题及其变体 LC 253,LC 370

树状数组

树状数组适合于经常进行原始数据修改的区间和问题,它可以把查找变成对数的时间复杂度。

树状数组3个核心函数:lowbit/query/add

  • 求前缀和的时候query一下左右边界
  • query的时候使用lowbit
  • add的时候使用lowbit

题目

LC 307 模版题

线段树

略(可参考后面的资料4.)

参考资料

  1. https://leetcode.cn/circle/discuss/mOr1u6/
  2. https://leetcode.cn/problems/range-sum-query-mutable/solutions/632515/guan-yu-ge-lei-qu-jian-he-wen-ti-ru-he-x-41hv
  3. https://lfool.github.io/LFool-Notes/algorithm/前缀后缀法.html
  4. https://lfool.github.io/LFool-Notes/algorithm/线段树详解.html
  5. https://blog.csdn.net/qq_40941722/article/details/104406126