
面试官手里的评分维度,通常不止“做出来没有”。常见的几项是:
问题澄清。 输入范围多大?有没有重复?空输入怎么处理?返回值是什么类型?能不能修改原数组?这些不问清楚,写出来的代码很可能答非所问。
思路表达。 能不能把暴力解说出来,再指出瓶颈,再给出优化方向。面试官要听的是“为什么这么想”,不是“答案是什么”。
复杂度分析。 时间、空间复杂度能说清,能比较不同方案的取舍。
代码质量。 命名清晰、结构合理、边界处理到位、没有明显 bug。
测试意识。 写完能不能自己构造用例验证,包括空、单元素、重复、极端值。
沟通与协作。 卡住时能不能说出自己的困惑,接受提示后能不能调整方向。
这六项里,只有“代码质量”和“做出来”是硬结果,其余都是过程分。而过程分,恰恰是大多数人丢分的地方。
比较稳妥的节奏是六步,时间分配大致如下(以 45 分钟为例):
1. 澄清问题(3—5 分钟)。 确认输入输出、数据范围、边界条件、是否有特殊约束。不要怕问,问清楚比写错强。
2. 举例验证(3—5 分钟)。 用一两个具体例子走一遍,确认自己理解对了。最好包含一个普通例子和一个边界例子。
3. 说思路(5—10 分钟)。 先说暴力解,再说优化方向。说清楚为什么优化、优化后复杂度变成多少。这一步面试官可能会给提示,要认真接。
4. 编码(10—15 分钟)。 写之前说一句“我开始写了”,写的时候保持结构清晰,变量命名有意义。不要 silent coding。
5. 自测(3—5 分钟)。 用刚才的例子手动走一遍,再补几个边界用例。发现 bug 不要慌,调试过程也是评分点。
6. 复盘(2—3 分钟)。 说清最终复杂度,提一下可能的改进或权衡。
这个节奏的核心是:先想清楚再写,写完要验证。很多人把 80% 时间花在编码上,结果思路没对齐,返工更费时间。
算法题千变万化,但思维框架有限。按“看到什么特征,想到什么工具”来记,比背题有效。
数组与字符串。 先想暴力,再看能不能用哈希换时间、用双指针降空间、用滑动窗口处理连续子段、用前缀和处理的区间查询。
链表。 双指针(快慢、前后)、哑节点处理头节点、原地反转。画图比空想有效。
二叉树。 递归是默认思路,想清楚“当前节点做什么、左右子树返回什么”。遍历顺序(前中后序)对应不同问题。
图。 BFS 求最短步数,DFS 求连通性,拓扑排序处理依赖,并查集处理连通分量。
动态规划。 先定义状态,再写转移,再定初始值和遍历顺序。想不清楚状态定义,就别急着写转移方程。
堆与 Top-K。 求最大 K 个用小顶堆,求最小 K 个用大顶堆,流式数据用堆维护。
二分。 有序或“单调性”是前提。难点在边界:left <= right 还是 left < right,mid 怎么取,更新时加不加一。写之前先把不变式说清楚。
回溯。 排列、组合、子集、棋盘类问题。框架是“选择—递归—撤销选择”,剪枝是优化重点。
框架的意义是给你一个起点,而不是让你套模板。面试官更想看到你根据题目特征选择合适的工具,而不是硬套。
误区一:上来就写代码。 没澄清、没举例、没说思路,写完发现理解错了,时间全浪费。
误区二:只追求最优解。 一上来就想 O(n),想不出来就卡住。先说暴力解,再优化,面试官反而更认可。
误区三:不说复杂度。 写完不分析时间和空间,面试官会认为你没有工程意识。
误区四:不测试。 写完就说“好了”,不自己走用例。边界 bug 往往就在这里暴露。
误区五:背题不理解。 碰到变体就懵。理解思路比记住代码重要。
误区六:卡住就沉默。 不说话会让面试官无法判断你的思路。说出卡在哪,往往能得到有效提示。
误区七:忽视代码风格。 变量叫 a、b、tmp,逻辑挤成一坨,即使结果对,评分也会打折。
误区八:不接受提示。 面试官给提示是在帮你,也是在观察你的协作能力。固执己见是减分项。
二分查找是典型的“看起来简单、写起来容易错”的题,很适合说明“边界意识”和“测试意识”。下面用 Python 写一个标准实现,重点不在代码长度,而在不变式和用例。
def lower_bound(nums, target):
"""返回第一个 >= target 的下标;不存在则返回 len(nums)。"""
lo, hi = 0, len(nums) # 搜索区间 [lo, hi)
while lo < hi: # 区间为空时结束
mid = (lo + hi) // 2
if nums[mid] < target:
lo = mid + 1 # 答案在右半区
else:
hi = mid # mid 可能是答案,保留
return lo
# 自测用例:普通、重复、边界、空
cases = [
([1, 3, 5, 7], 5, 2),
([1, 3, 3, 3, 7], 3, 1), # 重复元素取最左
([1, 3, 5], 0, 0), # 小于所有元素
([1, 3, 5], 9, 3), # 大于所有元素
([], 1, 0), # 空数组
]
for nums, t, expected in cases:
got = lower_bound(nums, t)
assert got == expected, (nums, t, got, expected)
print("all passed")这段代码值得讲的地方有三处。第一,搜索区间定义为左闭右开 [lo, hi),循环条件是 lo < hi,这样边界逻辑自洽,不容易死循环。第二,hi = mid 而不是 mid - 1,因为 mid 本身可能是答案。第三,自测用例覆盖了普通、重复、越界和空数组——这正是面试里应该主动展示的测试意识。
面试时不必写这么多注释,但先说清不变式、再写代码、最后用边界用例验证,这个顺序能让面试官看到你的工程习惯。
第一是沟通。算法面试本质是一次技术对话。能把思路说清楚、把困惑说出来、把取舍讲明白,比闷头写代码更重要。
第二是复杂度直觉。看到数据范围(比如 n ≤ 10^5),能立刻判断 O(n²) 不可行,从而排除某些方向。这种直觉来自对常见复杂度的熟悉。
第三是边界意识。空输入、单元素、重复值、负数、溢出、下标越界,这些是 bug 的高发区。写之前想一遍,写之后测一遍。
第四是调试能力。代码写错很正常,关键是能不能用例子快速定位。面试官往往更看重你“发现问题—定位问题—修正”的过程。
第五是心态。卡住时不慌,接受提示后能调整,做不出来时能说清自己的思路到了哪一步。面试不是考试,是一次协作。
算法面试的准备,不应该只是“刷够多少题”,而是练一套可复用的思考流程:澄清问题、举例验证、先说思路、再写代码、最后自测。题目会忘,模板会过时,但这套流程不会。真正让面试官记住你的,往往不是那道题做得多快,而是你在过程中展现出的清晰、严谨和协作感。把每一次练习都当成一次“讲给别人听”的演练,比单纯追求 AC 数量更有价值。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。