刷题主要参考labuladong的算法小抄,写的相当nice,有系统的刷题。一个月左右刷完。应付面试基本没有问题。
1 刷题心得
1 数据结构必刷,学了数据结构,有个框架思维,内功更强。
2 算法:计算机擅长的事情就是穷举(遍历)!我们要做的就是对一个问题实现聪明的穷举(利用一些先验信息排除不需要遍历的解),无遗漏的穷举。
聪明的穷举举例子:利用各种先验信息,最常见的排序信息,大小信息。二分。
2 数据结构
从存储角度来看,将其分为两类,数组(连续存储)以及链表(不连续存储)。其他数据结构都是在其基础上进行构造。
- 简单结构:栈与队列,处理扩容问题,数组链表都可以实现。
- 组合结构:散列表,数组加链表。树和图
- 常用:二叉树,二叉搜索树,单调栈,优先队列(二叉堆实现),
对数据结构的操作:增删改查
- 线性遍历, for+while
- 非线性遍历:递归 以二叉树为例
前序遍历:刚进入该节点
中序遍历:该节点左子树已经遍历完,然后进入该节点
后序遍历:将要离开该节点,此时可以用到的信息更多。
3 链表总结
a) 基本技巧
- 合并两个有序链表: 双指针
- 合并k个有序链表:优先队列,每次选出k个指针的最大或者最小。
from collections import PriorityQueue
Q=PriorityQueue()
Q.put()
Q.get()
堆的上浮与下沉 - 环形链表:快慢指针,每次多走一步,相差k步
- 寻找中间节点:快慢指针,快指针每次走两步
- 删除倒数第N个节点:快指针比慢指针一直快k步。
- 相交链表:双指针+交互处理(遍历完自己遍历对方)。
b) 晋级技巧
- 翻转整个链表:递归(翻转自己等于翻转自己的下一个节点开始的链表)+后序遍历(即将离开该节点,修改一个指针)。或者通过迭代实现,需要三个变量,pre,cur,nxt。
- 翻转前N个值:与反转整个类似,需要在递归时记录当前是第几个,写出base case,记:新的头结点。
- 翻转部分位置(m,n):递归+翻转前N个。
- k个一组翻转链表:迭代法更清晰。找到边界,然后递归。
4 数组总结
- 前缀和:需要频繁的求解数组和。
- 差分数组:对整段数组进行同样的操作
- 花式遍历:旋转图像:转为关于x,y轴或者对角线对称。螺旋矩阵:四个控制变量,右上和左下之间加入判断。或者一个圈数变量。
- 滑动窗口:两个while控制指针,字典记录关注的元素
- 二分搜索:
- 随机权重:前缀和+二分搜索边界
- 二分搜索优化问题求解:单调函数+初值
- 田忌赛马:按顺序排好,比得过的比,比不过用最差的比。
- 常数时间删除元素:字典记录每个元素的索引,与最后一个元素交换位置,然后删除最后一个元素。
- 数组去重:单调栈,新进来的元素与栈顶比较,不满足就删除。
4 二叉树总结
-
前中后序遍历: 前序遍历;对应第一次进入这个节点 只有之前的信息
中序遍历:对应左子树全部访问了 然后进入这个节点
后序遍历:要从这个节点离开,之前的信息全部都访问了 -
bfs层序遍历: 广度优先 一次往外扩张一圈 需要记录队列长度 for循环+while
-
序列化与反序列化
深度优先 一撸到底 先序遍历
遇到#return -
归并排序
天然的 左边索引大于右边索引! 可以计算翻转对 -
快速排序
是一棵二叉搜索树
通过交换位置解决
划分函数 传入 low 与high
下标low对应的元素为pivot,双指针 比较low+1,到high的元素与pivot的大小。返回 pivot对应的正确位置!找到第k大的,类似二叉树的剪枝操作,决定左右。 -
二叉搜索树
中序遍历有顺序!全局变量记录!
删除:找到左子树最大或者右子树最小的来交换位置 统一为base case
搜索:自带剪枝操作 根据大小决定遍历左树还是右树
插入:尽量插在尾端
验证:后序遍历
构造:选定一个 分左右 构造左右子树 -
后序遍历
不仅可以返回一个值!可以返回多个值 -
最近公共祖先:
后序遍历
把左右子树返回的东西 继续返回! -
完全二叉树
最多允许最后一层不满 并且先在左边 -
满二叉树 每一层都满了
5 设计数据结构总结
6回溯法+bfs总结
回溯:记住两个东西,状态加选择!当前的状态,以及一个选择池。
bfs:for+while+队列。一次向外扩张1+visited记录访问过的节点。
7 动态规划总结
较难的题一般转到后序遍历即可!
-
编辑距离 dp[i,j]有左上角三个元素决定
-
最长增长子序列 以i为结尾的最长增长子序列
-
最大子数组和 以i为结尾的最大子数组和
-
最长公共序列 属于难问题 倒着做!
将大问题转为多个小的子问题,比较小问题的大小。
一般需要写字典记录全局结果 -
最小路径和 简单问题
-
骑士求公主 较难问题倒着做
-
01背包
-
子集背包 为了求的dp[n][sum/2]是否为真
因此子问题也这么设计 bool变量
-
打家劫舍 选择 或者不选择
10.股票买卖
10.
8 贪婪法总结
- 区间覆盖问题