0x01 位运算
- 复杂度:用到位运算的代码时间复杂度一般都会带个log,选择算法时可以利用这一特点。
- 应用:位运算一般都用二进制实现,所以当每个物体有两种状态时一般可以用二进制数表示一个集合的状态。
- 注意:int变量的最大值在2^31-1,所以当表示的物体个数在30个以上时要慎用或开long long甚至更多。
0x02 递推与递归
- 复杂度:递推的时空复杂度一般不会太高,但是递归就非常不确定,所以需要特别注意。
- 应用:递推注重的是相邻两项关系的推导,而递归注重的是枚举和缩小问题。
- 注意:递归时很容易爆栈,要注意递归层数。
0x03 前缀和与差分
- 复杂度:主要注意是否爆空间。
- 应用:主要解决一些涉及到区间的问题。
- 注意:差分数组的前缀和就是原数组。
0x04 二分
- 复杂度:顾名思义——分成两份,所以时间复杂度一定带log。
- 应用:
- 二分查找:在一个单调序列里查找某一个值。
- 二分答案:在保证答案有单调性的情况下利用二分求最优解。相较于二分查找要难一些。
- 注意:二分答案中给mid赋值和缩小边界时要注意细节,实数域二分要确定好所需精度eps,以l + eps < r为循环条件。
0x05 排序
- 复杂度:最快的快排、归并排序和堆排序时间复杂度都为O(nlogn)。
- 应用:顾名思义——使有序。
- 注意:结构体和特殊顺序需要重载运算符或写cmp函数。
0x06 倍增
- 复杂度:顾名思义——成倍增长,时间复杂度带log,可用于选择法算法。
- 应用:解决RMQ问题以及求LCA。
0x07 贪心
- 复杂度:依情况而定。
- 应用:一般与排序结合,使用前需要证明正确性。
- 注意:证明方法大致有以下几种:
- 邻项交换
- 范围缩放
- 决策包容性
- 反证法
- 数学归纳法