引言
参照的是左程云的课程:https://space.bilibili.com/8888480/lists/3509640?type=series
本笔记是class048的内容,总结了二维前缀和、二维差分和离散化技巧的核心思想和应用。这些技巧是处理二维矩阵问题的重要工具,特别适用于矩形区域的批量查询和修改。
前置知识
在学习二维前缀和与差分之前,需要掌握以下基础知识:
- 一维前缀和与差分的原理
- 矩阵的基本操作
- 容斥原理的理解
- 坐标系统和索引处理
048【必备】二维前缀和、二维差分、离散化技巧
核心概念
二维前缀和的基本思想
二维前缀和是一维前缀和在二维空间的扩展:
- 原理:预处理出每个位置到左上角(0,0)的矩形区域和
- 查询优化:任意矩形区域的和查询在O(1)时间内完成
- 核心公式:使用容斥原理计算矩形区域和
二维差分的基本思想
二维差分用于优化矩形区域的批量修改:
- 原理:将矩形区域修改转化为四个关键点的修改
- 适用场景:大量矩形修改操作,最后统一查询
- 实现方式:通过四点修改实现区域增减,最后二维前缀和还原
离散化技巧
离散化用于处理坐标范围过大的问题:
- 核心思想:将大范围坐标映射到小范围数组
- 关键步骤:收集关键坐标、排序去重、建立映射关系
- 应用场景:坐标值很大但关键点有限的问题
题目一:二维前缀和模板
问题描述
给定一个二维矩阵matrix,实现一个类来处理以下类型的多次查询:
- 计算其子矩形范围内元素的总和,该子矩形的左上角为(row1, col1),右下角为(row2, col2)。
测试链接:https://leetcode.cn/problems/range-sum-query-2d-immutable/
核心思想
通过预计算二维前缀和,实现O(1)时间复杂度的矩形区域和查询:
- 前缀和构建:
s[i][j]存储从左上角(0,0)到右下角(i-1,j-1)的区域和 - 容斥原理:利用四个矩形的加减关系计算目标区域
- 边界处理:通过增加一圈0来简化边界判断
/class48-%E4%BA%8C%E7%BB%B4%E5%89%8D%E7%BC%80%E5%92%8C/%E5%89%8D%E7%BC%80%E5%92%8C%E7%9A%84%E5%85%AC%E5%BC%8F.png)
/class48-%E4%BA%8C%E7%BB%B4%E5%89%8D%E7%BC%80%E5%92%8C/%E6%B1%82%E4%BA%8C%E7%BB%B4%E6%95%B0%E7%BB%84%E5%AD%90%E6%95%B0%E7%BB%84%E7%9A%84%E5%92%8C.png)
/class48-%E4%BA%8C%E7%BB%B4%E5%89%8D%E7%BC%80%E5%92%8C/%E6%B1%82%E4%BA%8C%E7%BB%B4%E6%95%B0%E7%BB%84%E5%AD%90%E6%95%B0%E7%BB%84%E7%9A%84%E5%92%8C%E6%8A%BD%E8%B1%A1%E5%8C%96.png)
算法实现
1 | from typing import List |
容斥原理图解
1 | 查询矩形区域 (r1,c1) 到 (r2,c2) 的和: |
算法分析
- 预处理时间复杂度:O(n×m)
- 查询时间复杂度:O(1)
- 空间复杂度:O(n×m)
题目二:边框为1的最大正方形
问题描述
给你一个由若干0和1组成的二维网格grid,请你找出边界全部由1组成的最大正方形子网格,并返回该子网格中的元素数量。如果不存在,则返回0。
测试链接:https://leetcode.cn/problems/largest-1-bordered-square/
核心思想
利用二维前缀和快速验证正方形边框是否全为1:
- 边框验证:边框和 = 整个正方形和 - 内部正方形和
- 边框元素数量:边长为k的正方形边框有4×(k-1)个元素
- 枚举优化:从已知最大边长+1开始尝试,进行剪枝
/class48-%E4%BA%8C%E7%BB%B4%E5%89%8D%E7%BC%80%E5%92%8C/%E5%AF%BB%E6%89%BE%E6%9C%80%E5%A4%A7%E7%9A%84%E5%91%A8%E9%95%BF%E9%83%BD%E6%98%AF1%E7%9A%84%E5%9B%9B%E8%BE%B9%E5%BD%A2.png)
算法实现
1 | class Solution: |
算法分析
- 时间复杂度:O(n×m×min(n,m))
- 空间复杂度:O(1)(复用输入数组)
- 优化策略:剪枝搜索,从大边长开始尝试
题目三:二维差分模板
问题描述
给定一个n×n的矩阵,初始时所有元素都是0。进行q次操作,每次操作给定一个矩形区域(r1,c1)到(r2,c2),将该区域内所有元素加1。求所有操作完成后的矩阵。
测试链接:https://www.luogu.cn/problem/P3397
核心思想
使用二维差分数组优化矩形区域的批量修改:
- 四点修改:对矩形区域的修改转化为四个关键点的修改
- 差分还原:通过二维前缀和从差分数组还原最终结果
- 边界处理:使用额外的边界空间简化边界判断
/class48-%E4%BA%8C%E7%BB%B4%E5%89%8D%E7%BC%80%E5%92%8C/%E4%BA%8C%E7%BB%B4%E5%B7%AE%E5%88%86%E8%A1%A5%E5%81%BF.png)
关键函数解析
1 | def add(r1, c1, r2, c2, k): |
二维差分图解
1 | 原始矩形修改:对区域(r1,c1)到(r2,c2)加k |
完整实现
1 | import sys |
算法分析
- 时间复杂度:O(q + n²)
- 空间复杂度:O(n²)
- 核心优势:将每次O(n²)的区域修改优化为O(1)的四点修改
题目四:用邮票贴满网格图
问题描述
给你一个m×n的二进制矩阵grid,每个格子要么为0(空)要么为1(被占据)。给你邮票的尺寸为stampHeight×stampWidth。要求用邮票覆盖所有空格子,不覆盖任何被占据的格子。邮票可以相互重叠,但不允许旋转,必须完全在矩阵内。
测试链接:https://leetcode.cn/problems/stamping-the-grid/
核心思想
分两步解决:找出所有可贴位置,然后验证覆盖完整性:
- 可贴位置检测:使用二维前缀和快速判断区域是否全为0
- 覆盖标记:使用二维差分标记所有被邮票覆盖的位置
- 完整性验证:检查所有空格子是否都被覆盖
/class48-%E4%BA%8C%E7%BB%B4%E5%89%8D%E7%BC%80%E5%92%8C/%E5%A1%AB%E8%A1%A5%E9%82%AE%E7%A5%A8%E6%A1%88%E4%BE%8B.png)
/class48-%E4%BA%8C%E7%BB%B4%E5%89%8D%E7%BC%80%E5%92%8C/%E8%B4%B4%E9%82%AE%E7%A5%A8.png)
算法实现
1 | class Solution: |
算法分析
- 时间复杂度:O(n×m)
- 空间复杂度:O(n×m)
- 核心技巧:前缀和检测 + 差分标记
题目五:最强祝福力场(离散化技巧)
问题描述
小扣发现了带有「祝福」效果的力场,每个力场覆盖以坐标(x,y)为中心、边长为side的正方形区域。求力场强度最强处的力场强度(即覆盖该点的力场数量的最大值)。
测试链接:https://leetcode.cn/problems/xepqZ5/
核心思想
使用离散化技巧处理大坐标范围问题:
- 坐标收集:收集所有力场的边界坐标
- 坐标压缩:排序去重得到压缩坐标轴
- 映射转换:将原始坐标映射到压缩空间
- 差分处理:在压缩空间中进行二维差分操作
离散化原理
1 | # 离散化的核心步骤: |
/class48-%E4%BA%8C%E7%BB%B4%E5%89%8D%E7%BC%80%E5%92%8C/%E5%8A%9B%E5%9C%BA%E5%B9%B3%E7%A7%BB%E5%8F%98%E6%8D%A2.png)
算法实现
1 | import bisect |
离散化技巧总结
- 适用场景:坐标范围大但关键点少
- 核心步骤:收集→排序→去重→映射
- 空间优化:从O(坐标范围)降到O(关键点数量)
- 查找效率:使用二分查找进行坐标映射
算法分析
- 时间复杂度:O(n²log n)
- 空间复杂度:O(n²)
- 优化效果:坐标压缩后空间大大减少
技巧总结与应用场景
1. 二维前缀和应用场景
1 | # 适用情况: |
2. 二维差分应用场景
1 | # 适用情况: |
3. 离散化应用场景
1 | # 适用情况: |
复杂度分析对比
| 技巧 | 预处理 | 单次操作 | 空间复杂度 | 适用场景 |
|---|---|---|---|---|
| 二维前缀和 | O(n×m) | O(1)查询 | O(n×m) | 多查询少修改 |
| 二维差分 | O(1) | O(1)修改 + O(n×m)构建 | O(n×m) | 多修改后查询 |
| 离散化 | O(k log k) | 依赖具体算法 | O(k²) | 大坐标少关键点 |
学习建议
1. 理解容斥原理
- 掌握二维前缀和的数学基础
- 理解四个矩形的加减关系
- 练习边界处理技巧
2. 掌握差分思想
- 理解二维差分的四点修改原理
- 熟练掌握差分与前缀和的转换
- 注意边界扩展的重要性
3. 熟练离散化技巧
- 理解坐标压缩的核心思想
- 掌握二分查找在离散化中的应用
- 练习大坐标问题的转换
4. 综合应用能力
- 能够识别适合使用哪种技巧的问题
- 掌握多种技巧的组合使用
- 注意边界条件和特殊情况的处理
5. 调试技巧
- 验证前缀和构建的正确性
- 检查差分操作的边界
- 测试离散化映射的准确性
通过掌握二维前缀和、二维差分和离散化技巧,可以高效解决各种二维矩阵问题。关键在于理解每种技巧的适用场景,以及合理的边界处理和空间优化策略。