数据结构
什么是“数据结构”? 数据结构是计算机用来组织、存储和管理数据的方式。简单说,它回答的是一个问题: 数据应该怎样摆放,才能更方便、更高效地使用? 在程序中,我们不仅要“保存数据”,还要经常对数据进行操作,例如: 查找某个元素; 插入新数据; 删除旧数据; 修改数据; 遍历全部数据; 按某种规则排序或关联数据。 不同的数据结构,适合不同的操作场景。选对数据结构,程序可能非常高效;选错数据结构,程序可
在不进行网络搜索,不使用外部工具的情况下,你对自己最自信的知识领域是哪些?
数组
数组的“奇技淫巧”:本质是利用连续性和下标
数组最大的特点是:元素按顺序存放,可以通过下标快速访问。所以很多数组技巧,本质上都是在利用:
- 下标可以直接定位;
- 元素有固定顺序;
- 可以从左到右、从右到左扫描;
- 可以把数组本身当作“状态表”或“映射表”。
下面介绍一些常见又很实用的数组技巧。
1. 双指针:两个下标配合移动
双指针是数组题里最常见的技巧之一。它通常用两个变量表示位置,例如 left 和 right。
常见场景
- 反转数组;
- 删除重复元素;
- 判断回文;
- 有序数组中找两数之和;
- 原地移动元素。
例如,反转数组:
这个技巧的好处是:不需要额外数组,空间复杂度是 。
2. 快慢指针:原地过滤数组
快慢指针是双指针的一种变体。
fast负责遍历所有元素;slow负责记录“有效元素应该放在哪里”。
例如:删除数组中的某个值。
这里并没有真正删除元素,而是把需要保留的元素移动到前面。很多语言中的数组删除中间元素很慢,因为后面的元素要整体移动。快慢指针可以把多次移动优化成一次遍历。
3. 前缀和:快速求区间总和
如果你经常需要求数组某一段的和,例如 nums[l] 到 nums[r],每次循环累加会比较慢。
可以提前构造一个前缀和数组。
前缀和的核心公式是:
适合场景:
- 多次查询区间和;
- 统计子数组和;
- 二维矩阵区域求和;
- 配合哈希表解决“和为 K 的子数组”。
4. 差分数组:批量区间修改
前缀和适合“快速查询”,而差分数组适合“快速修改区间”。
假设你要对数组某个区间 [l, r] 都加上一个值,如果直接遍历区间,可能很慢。差分数组可以做到每次区间修改只改两个位置。
它的思想是:只记录变化从哪里开始,在哪里结束。
5. 滑动窗口:维护一段连续区间
滑动窗口常用于处理“连续子数组”或“连续子串”。
它通常有两个边界:
left:窗口左边界;right:窗口右边界。
例如,求长度为 k 的连续子数组最大和:
滑动窗口的关键是:窗口右移时,加入新元素,移除旧元素,不用每次重新计算。
6. 原地哈希:把数组当作标记表
有时候数组元素范围有限,可以利用数组下标做映射。
例如,判断数字是否出现过:
如果题目限制数字范围是 1 到 n,甚至可以把原数组本身当作标记空间。不过这种技巧要小心,因为它会修改原数组。
7. 哨兵技巧:减少边界判断
有些算法中,边界判断很多,可以加一个“哨兵”元素简化逻辑。
例如找最小值时,可以预设一个极大值:
float("inf") 就像一个无穷大的哨兵,任何正常数字都比它小。
8. 排序后再处理:降低问题难度
很多数组问题,一旦排序,就会变得简单。
例如:
- 找重复元素;
- 合并区间;
- 双指针找两数之和;
- 贪心选择;
- 统计频率。
不过排序通常需要:
所以要权衡:排序能简化逻辑,但也会增加时间成本,并且可能改变原数组顺序。
总结:数组技巧可以继续深入这些方向
如果你想继续钻研数组,可以重点学习:
- 双指针
- 快慢指针
- 前缀和
- 差分数组
- 滑动窗口
- 二分查找
- 原地修改
- 排序 + 贪心
- 数组模拟栈和队列
数组看起来简单,但它是很多高级数据结构和算法的基础。真正的“奇技淫巧”不是死记模板,而是理解:下标、顺序、连续区间、状态映射这几个核心思想。