推荐题目
不建议刷的题目类型:
- 非高频的hard题目,费时费力又很难在面试中遇到,性价比太低。
- 贪心法题目,每道题都不一样,解法没有通用性。
排序
- 基础知识:快速排序(Quick Sort), 归并排序(Merge Sort)的原理与代码实现。需要能讲明白代码中每一行的目的。快速排序时间复杂度平均状态下O(NlogN),空间复杂度O(1),归并排序最坏情况下时间复杂度O(NlogN),空间复杂度O(N)
- 入门题目:
- 进阶题目:
注意:215题是与快速排序非常相似的快速选择(Quick Select)算法,面试中很常考
链表
基础知识:链表如何实现,如何遍历链表。链表可以保证头部尾部插入删除操作都是O(1),查找任意元素位置O(N)
基础题目:
注意:快慢指针和链表反转几乎是所有链表类问题的基础,尤其是反转链表,代码很短,建议直接背熟。
堆、栈、队列、哈希表
Heap/Priority Queue:
二分法
基础知识:二分法是用来解法基本模板,时间复杂度logN;常见的二分法题目可以分为两大类,显式与隐式,即是否能从字面上一眼看出二分法的特点:要查找的数据是否可以分为两部分,前半部分为X,后半部分为O
显式二分法:
隐式二分法:
双指针
基础知识:常见双指针算法分为三类,同向(即两个指针都相同一个方向移动),背向(两个指针从相同或者相邻的位置出发,背向移动直到其中一根指针到达边界为止),相向(两个指针从两边出发一起向中间移动直到两个指针相遇)
背向双指针:(基本上全是回文串的题)
相向双指针:(以two sum为基础的一系列题)
- Leetcode 1. Two Sum (这里使用的是先排序的双指针算法,不同于hashmap做法)
- 167. 两数之和 II - 输入有序数组
- 15. 三数之和
- 16. 最接近的三数之和
- 18. 四数之和
- 454. 四数相加 II
- 11. 盛最多水的容器
同向双指针:(个人觉得最难的一类题,可以参考下这里 TimothyL:Leetcode 同向双指针/滑动窗口类代码模板)
宽度优先搜索
面试中最常考的
- 基础知识:
- 常见的BFS用来解决什么问题?(1) 简单图(有向无向皆可)的最短路径长度,注意是长度而不是具体的路径(2)拓扑排序 (3) 遍历一个图(或者树)
- BFS基本模板(需要记录层数或者不需要记录层数)
- 多数情况下时间复杂度空间复杂度都是O(N+M),N为节点个数,M为边的个数
- 基于树的BFS:不需要专门一个set来记录访问过的节点
- 基于图的BFS:(一般需要一个set来记录访问过的节点)
- 拓扑排序:(https://zh.wikipedia.org/wiki/%E6%8B%93%E6%92%B2%E6%8E%92%E5%BA%8F)
深度优先搜索
面试中最常考的(分类的稍微有点粗糙了,没有细分出回溯/分治来,准备找个时间给每个DFS的题标记下是哪种DFS)
- 基础知识:
- 常见的DFS用来解决什么问题?(1) 图中(有向无向皆可)的符合某种特征(比如最长)的路径以及长度(2)排列组合(3) 遍历一个图(或者树)(4)找出图或者树中符合题目要求的全部方案
- DFS基本模板(需要记录路径,不需要返回值 and 不需要记录路径,但需要记录某些特征的返回值)
- 除了遍历之外多数情况下时间复杂度是指数级别,一般是O(方案数×找到每个方案的时间复杂度)
- 递归题目都可以用非递归迭代的方法写,但一般实现起来非常麻烦
- 基于树的DFS:需要记住递归写前序中序后序遍历二叉树的模板
- 二叉搜索树(BST):BST特征:中序遍历为单调递增的二叉树,换句话说,根节点的值比左子树任意节点值都大,比右子树任意节点值都小,增删查改均为O(h)复杂度,h为树的高度;注意不是所有的BST题目都需要递归,有的题目只需要while循环即可
- 基于图的DFS: 和BFS一样一般需要一个set来记录访问过的节点,避免重复访问造成死循环; Word XXX 系列面试中非常常见,例如word break,word ladder,word pattern,word search。
- Leetcode 341 Flatten Nested List Iterator (339 364)
- 394. 字符串解码
- 51. N 皇后
- 341. 扁平化嵌套列表迭代器
- 93. 复原 IP 地址
- 22. 括号生成
- 856. 括号的分数***
- Leetcode 301 Remove Invalid Parentheses
- 37. 解数独
- Leetcode 212 Word Search II (I, II)
- 131. 分割回文串
- 基于排列组合的DFS: 其实与图类DFS方法一致,但是排列组合的特征更明显
- 记忆化搜索(DFS + Memoization Search):算是用递归的方式实现动态规划,递归每次返回时同时记录下已访问过的节点特征,避免重复访问同一个节点,可以有效的把指数级别的DFS时间复杂度降为多项式级别; 注意这一类的DFS必须在最后有返回值(分治法),不可以用回溯法; for循环的dp题目都可以用记忆化搜索的方式写,但是不是所有的记忆化搜索题目都可以用for循环的dp方式写。
- 139. 单词拆分
- 72. 编辑距离
- 377. 组合总和 Ⅳ
- 1235. 规划兼职工作***
- Leetcode 1335 Minimum Difficulty of a Job Schedule
- LCR 096. 交错字符串
- Leetcode 472 Concatenated Words
- 403. 青蛙过河***
- LCR 112. 矩阵中的最长递增路径
前缀和
基础知识:前缀和本质上是在一个list当中,用O(N)的时间提前算好从第0个数字到第i个数字之和,在后续使用中可以在O(1)时间内计算出第i到第j个数字之和,一般很少单独作为一道题出现,而是很多题目中的用到的一个小技巧
常见题目:
以上内容皆为面试中高频的知识点,以下知识点和题目在面试中属于中等频率(大概面10道题会遇到一次),时间不足的情况下,请以准备上面的知识点为主。
并查集
基础知识:如果数据不是实时变化,本类问题可以用BFS或者DFS的方式遍历,如果数据实时变化(data stream)则并查集每次的时间复杂度可以视为O(1);需要牢记合并与查找两个操作的模板
常见题目:
- Leetcode 721 Accounts Merge
- 547. 省份数量
字典树
基础知识:(https://zh.wikipedia.org/wiki/Trie);多数情况下可以通过用一个set来记录所有单词的prefix来替代,时间复杂度不变,但空间复杂度略高
常见题目:
- 208. 实现 Trie (前缀树)
- Leetcode 211 Design Add and Search Words Data Structure
- Leetcode 1268 Search Suggestions System
- Leetcode 212 Word Search II
单调栈与单调队列
基础知识:单调栈一般用于解决数组中找出每个数字的第一个大于/小于该数字的位置或者数字;单调队列只见过一道题需要使用;不论单调栈还是单调队列,单调的意思是保留在栈或者队列中的数字是单调递增或者单调递减的
常见题目:
扫描线算法
- 基础知识:一个很巧妙的解决时间安排冲突的算法,本身比较容易些也很容易理解
- 常见题目:
- 1094. 拼车
- Leetcode 218 The Skyline Problem
TreeMap
- 基础知识:基于红黑树(平衡二叉搜索树)的一种树状 hashmap,增删查改、找求大最小均为logN复杂度,Python当中可以使用SortedDict替代;SortedDict继承了普通的dict全部的方法,除此之外还可以peekitem(k)来找key里面第k大的元素,popitem(k)来删除掉第k大的元素,弥补了Python自带的heapq没法logN时间复杂度内删除某个元素的缺陷;最近又在刷一些hard题目时候突然发现TreeMap简直是个神技,很多用别的数据结构写起来非常麻烦的题目,TreeMap解决起来易如反掌。
- 常见题目:
- 729. 我的日程安排表 I***
- Leetcode 981 Time Based Key-Value Store
- 846. 一手顺子*
- Leetcode 218 The Skyline Problem
- Leetcode 480. Sliding Window Median (这个题用TreeMap超级方便)
- 318. 最大单词长度乘积
动态规划
- 基础知识:这里指的是用for循环方式的动态规划,非Memoization Search方式。DP可以在多项式时间复杂度内解决DFS需要指数级别的问题。常见的题目包括找最大最小,找可行性,找总方案数等,一般结果是一个Integer或者Boolean。动态规划有很多分支,暂时还没想好怎么去写这部分,后面想好了再具体写吧。
- 常见题目:
- 674. 最长连续递增序列
- 62. 不同路径
- 70. 爬楼梯
- 64. 最小路径和
- 368. 最大整除子集
- 300. 最长递增子序列
- Leetcode 354 Russian Doll Envelopes (接龙型dp, 300的2D版)
- 121. 买卖股票的最佳时机
- 55. 跳跃游戏
- 45. 跳跃游戏 II
- 132. 分割回文串 II
- Leetcode 312 Burst Balloons (区间型dp)
- 1143. 最长公共子序列
- 718. 最长重复子数组
- Leetcode 174 Dungeon Game
- 115. 不同的子序列
- 72. 编辑距离
- 91. 解码方法
- Leetcode 639 Decode Ways II
- Leetcode 712 Minimum ASCII Delete Sum for Two Strings
- 221. 最大正方形
- 221. 最大正方形
- 198. 打家劫舍
- 213. 打家劫舍 II
- Leetcode 740 Delete and Earn
- Leetcode 87 Scramble String
- Leetcode 1140 Stone Game II
- Leetcode 322 Coin Change
- Leetcode 518 Coin Change II (01背包型)
- Leetcode 1048 Longest String Chain
- Leetcode 44 Wildcard Matching
- Leetcode 10 Regular Expression Matching
- Leetcode 32 Longest Valid Parentheses
- Leetcode 1235 Maximum Profit in Job Scheduling (DP + binary search)
- Leetcode 1043 Partition Array for Maximum Sum
- Leetcode 926 Flip String to Monotone Increasing