讲解

走到这里,24 种核心模式已经过完。最后一章不谈新算法,谈如何让已有的功夫在面试和日常练习中稳定发挥。先说选题策略:不要按题号顺序刷,按模式刷——本教程的章序就是一份现成的路线图。每个模式先做 2-3 道经典题建立手感(本章前面各章示例里的题目就是精选),再做 2 道变体题检验是否真的理解模式而不是背了答案。LeetCode 热题 100、剑指 Offer 这类榜单的价值在于频率,不在权威。

复盘比刷题量重要十倍。每道题做完(或卡壳后看题解)记三条:这题识别信号是什么(下次见到什么特征该想起这个模式)、我卡在哪一步(建模?边界?复杂度估算?)、最优解和我解法的差距在哪。一本几十条的复盘笔记,比一千道刷完就忘的题有用得多。两周后重做卡过的题,能独立写出才算消化。

面试现场的方法论可以压缩成四步。一、澄清题意:确认输入范围、是否有序、能否有重复值、空输入怎么办——这一步既是信息收集也是思考时间。二、先讲暴力解再优化:「暴力是 O(n²) 枚举,我观察到……可以优化到 O(n)」的叙述方式,展示的是思维路径而不只是答案。三、边写边讲:命名、边界判断的理由说出声,沉默写代码是大忌。四、主动做复杂度分析和自查:写完先说时空复杂度,再主动过一遍边界用例——把面试官的追问提前自问自答。

最后是复杂度速查这个实用工具:面试官给出数据规模时,要能立刻反推出可接受的算法复杂度(第二章的锚点)。把它做成一张条件反射表:n <= 12 可以阶乘暴搜,n <= 25 可以指数枚举,n 几百可以立方,n 几千可以平方,n 十万要 n log n,再大必须线性或对数。这张表值得背到脱口而出。

示例

把「复杂度速查表」和「写完代码后的自检清单」写成可执行的小工具——方法论也可以代码化:

import assert from 'node:assert/strict';

// 按每秒约 1e8 次简单运算估算:给定数据规模 n,可接受的复杂度上限
function advisedComplexity(n) {
  if (n <= 12) return 'O(n!) 或 O(2^n):可以全排列/全子集暴搜';
  if (n <= 25) return 'O(2^n):可以子集枚举、状态压缩';
  if (n <= 500) return 'O(n^3) 可接受';
  if (n <= 5000) return 'O(n^2) 可接受';
  if (n <= 100000) return 'O(n log n):排序、堆、二分';
  return '必须是 O(n) 或 O(log n):哈希、双指针、单调栈';
}

// 面试写完代码后的自检清单:逐项过一遍再交卷
function selfChecklist() {
  return [
    '边界:空输入、单元素、最大值都试过了吗',
    '复杂度:时间和空间能向面试官说清吗',
    '变体:如果数组有序 / 允许重复 / 内存放不下,解法怎么变',
    '正确性:能用小例子手跑一遍并给出测试用例吗',
  ];
}

assert.strictEqual(advisedComplexity(10), 'O(n!) 或 O(2^n):可以全排列/全子集暴搜');
assert.strictEqual(advisedComplexity(20), 'O(2^n):可以子集枚举、状态压缩');
assert.strictEqual(advisedComplexity(1000), 'O(n^2) 可接受');
assert.strictEqual(advisedComplexity(50000), 'O(n log n):排序、堆、二分');
assert.ok(advisedComplexity(10_000_000).startsWith('必须是'));

const list = selfChecklist();
assert.strictEqual(list.length, 4);
assert.ok(list.every((item) => item.length > 0));

console.log('n=50000 时的建议:', advisedComplexity(50000));
console.log('自检清单共', list.length, '项:');
for (const item of list) console.log(' -', item);

运行输出就是一张随身卡片。把 advisedComplexity 的判断边界背下来,面试时听到「数组长度不超过 10⁵」应立刻反射出「排序 / 堆 / 二分级别,平方会超时」。

常见坑

  • 按题号顺序刷题:模式被打散在题海里,效率极低;按模式集中突破。
  • 刷完不复盘:同一模式换个皮就认不出来,说明复盘缺失;卡壳题两周后重做。
  • 面试直接开写最优解:跳过澄清和暴力解,既容易理解错题意,也剥夺了面试官看思考过程的机会。
  • 沉默写代码:面试官无法评估卡住的人该不该救;边写边讲思路,卡壳也能拿到提示。
  • 忽略复杂度追问:「还能更快吗」「空间能优化吗」几乎是必考题,写完主动先答。

小结

按模式刷题、用复盘笔记消化、面试四步(澄清 → 暴力 → 优化 → 自查)、数据规模反推复杂度。至此 24 章全部完成——剩下的路只有一条:打开题库,把这些模式用到纯熟。祝面试顺利。