coding-practicing

lifelong learning & practice makes perfect

View the Project on GitHub programnotes/coding-practicing

常见题型

以下8个门类是面试中最常考的算法与数据结构知识点。 来源,知乎

排序类(Sort)

基础知识:快速排序(Quick Sort), 归并排序(Merge Sort)的原理与代码实现。需要能讲明白代码中每一行的目的。快速排序时间复杂度平均状态下O(NlogN),空间复杂度O(1),归并排序最坏情况下时间复杂度O(NlogN),空间复杂度O(N) 入门题目: Leetcode 148. Sort List Leetcode 56. Merge Intervals Leetcode 27. Remove elements 进阶题目:

链表类(Linked List)

基础知识:链表如何实现,如何遍历链表。链表可以保证头部尾部插入删除操作都是O(1),查找任意元素位置O(N) 基础题目: Leetcode 206. Reverse Linked List Leetcode 876. Middle of the Linked List 注意:快慢指针和链表反转几乎是所有链表类问题的基础,尤其是反转链表,代码很短,建议直接背熟。

进阶题目:

堆(Heap or Priority Queue)、栈(Stack)、队列(Queue)、哈希表类(Hashmap、Hashset)

基础知识:各个数据结构的基本原理,增删查改复杂度。 Queue题目:

基础知识:二分法是用来解法基本模板,时间复杂度logN;常见的二分法题目可以分为两大类,显式与隐式,即是否能从字面上一眼看出二分法的特点:要查找的数据是否可以分为两部分,前半部分为X,后半部分为O 显式二分法:

隐式二分法:

解题

binary search

其他

leetcode 二分查找学习计划

双指针(2 Pointer)

基础知识:常见双指针算法分为三类,同向(即两个指针都相同一个方向移动),背向(两个指针从相同或者相邻的位置出发,背向移动直到其中一根指针到达边界为止),相向(两个指针从两边出发一起向中间移动直到两个指针相遇) 背向双指针:(基本上全是回文串的题)

宽度优先搜索(BFS):面试中最常考的

基础知识: 常见的BFS用来解决什么问题?(1) 简单图(有向无向皆可)的最短路径长度,注意是长度而不是具体的路径(2)拓扑排序 (3) 遍历一个图(或者树) BFS基本模板(需要记录层数或者不需要记录层数) 多数情况下时间复杂度空间复杂度都是O(N+M),N为节点个数,M为边的个数 基于树的BFS:不需要专门一个set来记录访问过的节点

深度优先搜索(DFS)

面试中最常考的(分类的稍微有点粗糙了,没有细分出回溯/分治来,准备找个时间给每个DFS的题标记下是哪种DFS)

基础知识: 常见的DFS用来解决什么问题?(1) 图中(有向无向皆可)的符合某种特征(比如最长)的路径以及长度(2)排列组合(3) 遍历一个图(或者树)(4)找出图或者树中符合题目要求的全部方案 DFS基本模板(需要记录路径,不需要返回值 and 不需要记录路径,但需要记录某些特征的返回值) 除了遍历之外多数情况下时间复杂度是指数级别,一般是O(方案数×找到每个方案的时间复杂度) 递归题目都可以用非递归迭代的方法写,但一般实现起来非常麻烦 基于树的DFS:需要记住递归写前序中序后序遍历二叉树的模板

前缀和(Prefix Sum)

基础知识:前缀和本质上是在一个list当中,用O(N)的时间提前算好从第0个数字到第i个数字之和,在后续使用中可以在O(1)时间内计算出第i到第j个数字之和,一般很少单独作为一道题出现,而是很多题目中的用到的一个小技巧 常见题目:

次一级

以上内容皆为面试中高频的知识点,以下知识点和题目在面试中属于中等频率(大概面10道题会遇到一次),时间不足的情况下,请以准备上面的知识点为主。

并查集(Union Find):把两个或者多个集合合并为一个集合

基础知识:如果数据不是实时变化,本类问题可以用BFS或者DFS的方式遍历,如果数据实时变化(data stream)则并查集每次的时间复杂度可以视为O(1);需要牢记合并与查找两个操作的模板 常见题目:

字典树(Trie)

基础知识:(https://zh.wikipedia.org/wiki/Trie);多数情况下可以通过用一个set来记录所有单词的prefix来替代,时间复杂度不变,但空间复杂度略高 常见题目:

单调栈与单调队列(Monotone Stack/Queue)

基础知识:单调栈一般用于解决数组中找出每个数字的第一个大于/小于该数字的位置或者数字;单调队列只见过一道题需要使用;不论单调栈还是单调队列,单调的意思是保留在栈或者队列中的数字是单调递增或者单调递减的 常见题目:

扫描线算法(Sweep Line)

基础知识:一个很巧妙的解决时间安排冲突的算法,本身比较容易些也很容易理解 常见题目:

TreeMap

基础知识:基于红黑树(平衡二叉搜索树)的一种树状 hashmap,增删查改、找求大最小均为logN复杂度,Python当中可以使用SortedDict替代;SortedDict继承了普通的dict全部的方法,除此之外还可以peekitem(k)来找key里面第k大的元素,popitem(k)来删除掉第k大的元素,弥补了Python自带的heapq没法logN时间复杂度内删除某个元素的缺陷;最近又在刷一些hard题目时候突然发现TreeMap简直是个神技,很多用别的数据结构写起来非常麻烦的题目,TreeMap解决起来易如反掌。 常见题目:

动态规划(Dynamic Programming)

基础知识:这里指的是用for循环方式的动态规划,非Memoization Search方式。DP可以在多项式时间复杂度内解决DFS需要指数级别的问题。常见的题目包括找最大最小,找可行性,找总方案数等,一般结果是一个Integer或者Boolean。动态规划有很多分支,暂时还没想好怎么去写这部分,后面想好了再具体写吧。 常见题目:

题解