本文目录导读:
针对算法与数据结构面试,面试官通常希望候选人在有限的时间(通常20-45分钟)内,写出无bug、高效、健壮的代码,以下是按考察频率和重要性整理的核心知识点,同时附带了源码面试中的具体考察形式和应对策略。
核心数据结构(必考,90%以上)
这些是算法题的“砖块”,必须能 “手撕” 其核心操作。
-
数组(Array)与字符串(String)
- 高频操作:双指针(快慢、左右对撞)、滑动窗口、前缀和、原地修改。
- 经典题:最长无重复子串、三数之和、接雨水(高频难题)。
-
链表(Linked List)
- 核心考点:指针操作、边界条件(空、一个节点、两个节点)。
- 必会题:反转链表(迭代+递归)、合并两个有序链表、环形链表检测(快慢指针)、删除倒数第N个节点。
-
哈希表(HashMap / HashSet)
- 核心考点:O(1)查找、去重、计数。
- 必会题:两数之和(LeetCode第一题)、字母异位词分组、LRU缓存(结合双向链表,面试极高概率)。
-
栈与队列(Stack & Queue)
- 变种:单调栈、单调队列。
- 必会题:有效的括号(栈的经典应用)、最小栈、用队列实现栈/用栈实现队列、滑动窗口最大值(单调队列)。
-
树(Tree)与二叉树(Binary Tree)
- 核心:递归(绝大多数树问题的基础)、遍历(前中后序、层序)。
- 必会题:二叉树的最大/最小深度、验证二叉搜索树(BST)、二叉树的最近公共祖先、二叉树的序列化与反序列化、路径总和。
核心算法思想(重灾区)
这是面试的难点,考察逻辑思维和优化能力。
-
递归与回溯(Backtracking)
- 核心:决策树、剪枝、状态恢复。
- 必会题:全排列、子集、组合总和、N皇后问题。
-
深度优先搜索(DFS)与广度优先搜索(BFS)
- DFS:通常用递归,适合路径、连通性问题。
- BFS:通常用队列,适合最短路径、层级遍历、拓扑排序。
- 必会题:岛屿数量(DFS/BFS均考)、课程表(拓扑排序)。
-
动态规划(Dynamic Programming, DP)
- 难度:中等偏难,是区分面试者水平的关键。
- 必会模型:
- 线性DP:斐波那契、打家劫舍、最长递增子序列(LIS)。
- 区间DP:最长回文子串。
- 背包问题:01背包(分割等和子集)、完全背包(零钱兑换)。
- 状态定义:
dp[i]或dp[i][j]的含义是解题核心。
-
排序与搜索
- 排序:快速排序(手撕)、归并排序(手撕)、堆排序(理解)。
- 搜索:二分查找(极其重要,变形题很多)、旋转排序数组中的搜索。
-
贪心算法(Greedy)
- 核心:局部最优推导全局最优(需证明或直觉)。
- 必会题:跳跃游戏、区间调度(最多无重叠区间)。
进阶与常考难题(出现频率高)
这些是拉开分差的关键。
-
图论(Graph)基础
- 图的表示(邻接矩阵/邻接表)、拓扑排序(BFS Kahn算法)、最短路径(Dijkstra,时间复杂度证明)、并查集(Union-Find,连通性问题)。
- 必会题:课程表(拓扑排序)、朋友圈(并查集)、网络延迟时间(Dijkstra)。
-
设计题(OOP/系统设计简化版)
- LRU缓存:面试中的“明星题”,必会。
- 线程安全:单例模式(双检锁、静态内部类)、生产者消费者模型(
BlockingQueue)。 - 数据流:实时中位数(两个堆)、Top K问题(堆/快速选择)。
-
位运算(Bit Manipulation)
- 常见技巧:
n & (n-1)消除最低位1、异或()找唯一不重复数。 - 必会题:只出现一次的数字、2的幂、比特位计数。
- 常见技巧:
-
字符串高级
正则表达式匹配(动态规划)、KMP(了解next数组,手撕有难度但加分)。
源码面试中的“软实力”考察点
面试官看重的不仅仅是最终答案,更看重推导过程。
-
Clarification(明确需求):
- 开始写代码前,先问清楚:输入范围?是否包含重复?空值处理?是否有序?遇到
int溢出怎么办? - 旋转数组搜索,先问是否含重复元素(影响二分查找条件)。
- 开始写代码前,先问清楚:输入范围?是否包含重复?空值处理?是否有序?遇到
-
Time & Space Complexity(时空复杂度):
- 每写完一个解法,面试官必问。“能优化吗?”
- 暴力法是O(n^2),你能用哈希表优化到O(n)吗?
-
Edge Cases(边界条件):
- 主动写出对特殊输入(
null、空数组、单元素数组、全重复、最大最小值)的处理。 - 反转链表时,
head == null或head.next == null的提前返回。
- 主动写出对特殊输入(
-
Code Style(代码风格):
- 命名规范(
i可以用,但currentIndex更好)。 - 逻辑清晰,减少不必要的嵌套(使用
continue/return提前结束)。 - 适当加注释(关键逻辑)。
- 命名规范(
-
Testing(测试能力):
- 代码写完后,主动提出:“我写几个测试用例验证一下”。
- 正常情况、边界情况、负数/大数情况。
高效准备策略(针对已掌握基础语法的同学)
-
按“类型”刷题,而非按“题号”:
- 不要随机刷,先花2-3天集中刷链表,再集中刷二叉树,最后刷动态规划,每个类型连刷15-20题,归纳总结出“解题模板”。
-
背诵“题眼”:
- 看到“连续子数组/子串” → 滑动窗口或前缀和。
- 看到“第K大/小” → 堆或快速选择。
- 看到“Top K” → 最小堆或快速排序(快排也能用来找Top K)。
- 看到“链表相交/环” → 快慢指针。
- 看到“最值/计数/方案数”且可以分解为子问题 → 动态规划。
- 看到“所有组合/排列/路径” → 回溯。
-
精刷而非海刷:
一道题做对后,花10分钟思考:能否优化?能否写出递归+迭代两种版本?如果面试官改变限制条件(如数组变为链表),如何调整代码?
-
找到“必背”代码:
- 快速排序(双指针版)
- 归并排序(分治版)
- 反转链表(迭代+递归)
- 二分查找(标准版 + 寻找左右边界版)
- 全排列(回溯模板)
- 二叉树遍历(迭代版,特别是中序和后序)
- 并查集(含路径压缩)
- Dijkstra(优先队列版)
总结一句话:算法面试源码重点在于通过代码展示你的逻辑推导、边界处理和优化意识,建议优先掌握:哈希表、双指针、递归/回溯、二叉树、动态规划这五大板块,它们覆盖了80%以上的面试题。