← 12套面试训练

LOOP 02 / INTERVIEW LOOP / 4H

压缩相邻重复:先听清“重复”的意思

日志里相邻相同的状态不必重复显示,但隔了一次变化后再次出现的状态必须保留。你需要说明为什么“去重”不能直接理解为放进一个集合。

完成单元 21 · 插入结果与容器适配器及其先备后安排本次训练。不绑定日历周。

先写自己的答案,再展开参考。这里按技能编写问题,不声称公司真题;自评与阅读都不会自动通过 G0。

先备与学习位置

回到对应的路线里程碑 →

TIME WITH OUTPUTS

240 分钟怎样用

  1. 闭卷恢复先备 · 15min

    用 [] 和 [2] 解释 vector 的 size/back 前提;写出 const vector 引用与返回新 vector 的所有权区别。

    留下:先不查章节,写三条判断和一个不确定点;再只补读相关章节的解释段。

  2. 澄清题目与手算 · 25min

    读主问题,逐条写输入、输出、范围与失败行为。手算前两个公开用例,给自己的方案找一个反例。

    留下:一份接口合同、逐步状态表和最小反例;不要先打开参考推演。

  3. 独立实现或设计 · 55min

    实现 compact_runs(const std::vector<int>& input),返回一个新 vector,只保留每段连续相同整数的第一个。输入最多 100 项,每项在 [-100,100];本周用 vector、下标或顺序遍历即可。

    留下:保存个人代码或设计稿。编码题保留编译命令;设计题为每个事件编号,不能只画没有状态的箭头。

  4. 边界与反证 · 25min

    用题目的全部公开用例核对真实输出;另外创造一个与公开输入不同的边界。发现失败时缩小输入,再解释修复。

    留下:实际结果、原始失败和修复原因各一份;设计题记录一个被拒绝的执行顺序。

  5. 按表现进入追问树 · 35min

    从 n1 开始。每题先录下自己的回答,再展开标准;按满足或未满足条件跳转。树最多走一轮,卡住时把剩余时间用于分支中的纠错,不循环加时。

    留下:记录经过的节点、原话、缺失条件和修订;只会复述标准的节点仍标记待重做。

  6. 英文口述与打断 · 30min

    用本页英文提纲录制两轮 90 秒回答;第二轮在 30 秒处自问追问,先回答追问再回到主线。每轮回听并改写两个含糊句。

    留下:两轮录音或逐字稿;圈出输入、因果、边界和限制各一句。参考英文在录完第一轮后再读。

  7. 复盘与安排重做 · 25min

    对照强弱答案,选择一个真正出错的环节:合同、状态、实现、验证或表达。填本页记录模板,并约定下一天的 30 分钟。

    留下:一个有失败输入的错误记录和一个可观察修复标准;不要把全部问题归因为粗心。

  8. 次日无答案重做 · 30min

    次日把题目改为输出每段的长度,不输出数值。可只返回 vector<int> 的长度列表,不需要新类;输入 [5,5,2,2,2,5]、[]、[0]。

    留下:这是本周 240 分钟中的最后 30 分钟,不另加预算。先关闭解答,用 20 分钟独立做,再用 10 分钟核验并记录是否仍需复习。

包括次日重做,总计 240min。局部错因复盘属于本次练习,额外的计划复盘按实际需要另记。

SOLVE BEFORE READING THE ANSWER

先独立处理这个问题

实现 compact_runs(const std::vector<int>& input),返回一个新 vector,只保留每段连续相同整数的第一个。输入最多 100 项,每项在 [-100,100];本周用 vector、下标或顺序遍历即可。

输入与输出合同

  • 不改变输入,不对它排序。
  • 只合并相邻重复,非相邻重复保留。
  • 空输入返回空 vector;不要在空 vector 上调用 back()。
手算之后,对照公开用例
输入或情形预期为什么
[][]没有第一项可读取。
[3,3,1,1,3][3,1,3]末尾的 3 属于新的一段。
[4,4,4][4]一整段只输出一次。
[1,2,1][1,2,1]非相邻重复不合并。
[-1,-1,0,0,-1][-1,0,-1]不能拿 0 当不存在的哨兵。

先保留自己的解法、状态轨迹与验证记录,再打开参考。允许用自然语言或伪代码补充解释;不能用参考输出代替真实运行。

保存独立尝试后,阅读解法与状态轨迹

解法依据

从空结果开始,依次看输入值 x;若结果为空,或者结果最后一项不等于 x,就追加 x。先判空再访问 back,利用条件短路保证空结果不会被读取。每个输入检查一次,结果最多与输入等长。不需要排序;排序会丢失日志顺序。

逐步推演

[3,3,1,1,3]:读第一个 3 得 [3];第二个 3 不变;第一个 1 得 [3,1];第二个 1 不变;最后的 3 与结果尾部 1 不同,得到 [3,1,3]。

FOLLOW THE ANSWER, NOT A SCRIPT

从回答进入下一层追问

n1 开始。先录下回答,再展开判定;达到条件就走深入分支,未达到就按反馈缩小问题。一次最多走一轮,不靠反复查看同一答案累积“通过”。

把实际走过的节点记入模板 →

NODE n1

为什么 [1,2,1] 不能返回 [1,2]?

我已作答:查看判定与下一分支

需要解释清楚:两个 1 中间发生了状态变化;相邻压缩必须保留第二段 1。

达到

结论正确,并解释本节点给出的具体状态或反例。

保留关键推理:两个 1 中间发生了状态变化;相邻压缩必须保留第二段 1。

继续到 n2 →

待补

只报术语、漏掉条件,或不能解释题中的数值。

给每个输入写段编号 0、1、2,逐段选择首项。

继续到 r1 →

NODE r1

把第一个追问缩到最小输入,重新逐步说明。

我已作答:查看判定与下一分支

需要解释清楚:两个 1 中间发生了状态变化;相邻压缩必须保留第二段 1。

修复后达到

用具体输入改正原回答,能指出之前错在哪里。

给每个输入写段编号 0、1、2,逐段选择首项。

继续到 n2 →

仍未达到

仍依赖答案复述,不能独立重建状态。

本次树到此结束;把 n1 的输入和缺口写入复盘,再进入英文练习与次日重做。

这一分支结束:对照并复盘 →

NODE n2

能写成 out.back()!=x || out.empty() 吗?

我已作答:查看判定与下一分支

需要解释清楚:不行,左侧先执行,空结果会先调用 back;必须先判空,或用显式 if 分开。

达到

结论正确,并解释本节点给出的具体状态或反例。

保留关键推理:不行,左侧先执行,空结果会先调用 back;必须先判空,或用显式 if 分开。

继续到 n3 →

待补

只报术语、漏掉条件,或不能解释题中的数值。

用最小非空 input=[5]、初始 output=[] 走第一次循环,逐项说明 out.back()!=x || out.empty() 的求值顺序;定位先调用 back 的非法前提。空 input 不进入循环,不能触发这个错误。

继续到 n3 →

NODE n3

保留指向 input 的 view,再向 input 追加数据,有什么隐患?

我已作答:查看判定与下一分支

需要解释清楚:追加可能使 vector 重新分配,旧借用可能失效;本接口使用 const 引用且不追加输入,新结果独立拥有存储。

达到

结论正确,并解释本节点给出的具体状态或反例。

保留关键推理:追加可能使 vector 重新分配,旧借用可能失效;本接口使用 const 引用且不追加输入,新结果独立拥有存储。

这一分支结束:对照并复盘 →

待补

只报术语、漏掉条件,或不能解释题中的数值。

画输入 owner 和新输出 owner 两块内存,再标出借用箭头。

这一分支结束:对照并复盘 →

答案强在哪里,弱在哪里

保存自己的回答后,打开对照

弱答案

“用 set 去重,输出 1、3;我可以先排序再 unique。”

强答案

“要求保留段的先后次序,所以我比较的是当前值和最后一次保留的值。对 3、3、1、1、3 应输出 3、1、3;全局去重或排序都破坏了这个合同。”

强答案用同一个输入证明两类“重复”不同,说明空容器安全,再讨论一次遍历。不是只报一个标准库 API 名称。

在自己的原回答里划出一个缺失的条件或错误推理,再重说一遍。完整句子背熟,不代表能处理新约束。

ANSWER, THEN HANDLE AN INTERRUPTION

英文口述与打断

Explain consecutive deduplication to someone who suggested a set.

  1. Define a run.
  2. Use 3,3,1,1,3 as a counterexample.
  3. Mention empty output before back().

“Why not sort first?”

录完第一轮后,读英文示范
A run is a consecutive group of equal values. I preserve one value per run, so three, three, one, one, three becomes three, one, three. A set would remove the final three and lose the sequence. I check whether the output is empty before reading its last element.
  • 前 15 秒说明输入、输出和一个关键约定。
  • 至少用一个本题的数值解释因果,不只罗列英文术语。
  • 明确一个边界或尚未验证的限制;不能把教学推演说成项目经验。

次日关掉解答,换一个问题

次日把题目改为输出每段的长度,不输出数值。可只返回 vector<int> 的长度列表,不需要新类;输入 [5,5,2,2,2,5]、[]、[0]。

独立重做后核对

[5,5,2,2,2,5]→[2,3,1];[]→[];[0]→[1]。所有段长度之和必须等于输入长度;总段数等于主问题压缩后长度。

  • 关闭主问题答案并使用新输入独立完成。
  • 给出结果与原因;失败时记录最小反例,不能只把完成标记改成通过。

重做的 30min 已计入本套4h;需要更多补课时记录实际用时,按缺口顺延。

记录实际回答与证据

本次面试练习模板
# W02 算法 / 英文训练记录(仅个人练习,不是能力认证)
日期:
本次先备与尚不确定点:
主问题接口合同:
我最初的方案与状态表:
运行命令或设计事件编号:
失败输入 / 预期 / 实际:
修复与理由:
追问路径(节点 → 自己原话 → 缺口):
英文第一轮两处含糊句:
英文第二轮修订:
次日重做日期(30 分钟已含本周预算):
重做输入 / 实际结果 / 解释:
仍需补练:

本次练习的检查依据

保持输入和顺序,空输入安全;能用 [1,2,1] 否定全局去重,并独立完成次日段长度版本。

模板在你的个人笔记中填写。网页只提供空模板;不会把这次训练写成项目经验或学习验收结果。