跳到正文
算法刷题与面试

从题意写出形式化规格

20 分钟

开课第一件事:先确认我们在解同一道题

这是刷题课第一课,没有前课要补。面试中最可惜的失败不是不会算法,而是题目要“返回下标”,你却返回了两个数值。老师用 Two Sum 带你把自然语言压成可检查的规格,再开始写代码。

题目说:给定整数数组 nums 和整数 target,找出两个不同位置,使它们的元素之和等于 target。假设恰好有一组答案,返回两个下标。

把它拆成四类信息:

  1. 输入域与规模:nums 是整数数组,长度至少 2;target 是整数。
  2. 输出关系:返回 [i,j],满足 i != jnums[i]+nums[j]==target
  3. 边界与无解约定:本题保证唯一解,因此不用定义无解返回值;允许负数和重复值。
  4. 资源限制:若 n 很大,O(n²) 双循环可能超时,目标是 O(n) 时间、O(n) 空间。

从规格推导算法,而不是背模板

扫描到值 x 时,我们需要知道此前是否出现过 target-x。哈希表保存“值→下标”。以 nums=[2,7,11,15],target=9 为例:

i x 需要 表(检查前) 动作
0 2 7 {} 存 2→0
1 7 2 {2:0} 找到,返回 [0,1]

必须先查再存。若输入 [3,3]、target=6,第一轮存 3→0,第二轮才能用不同下标匹配;若先存再查,第一轮可能错误地让一个元素和自己配对。

def two_sum(nums, target):
    seen = {}
    for i, x in enumerate(nums):
        need = target - x
        if need in seen:
            return [seen[need], i]
        seen[x] = i
    raise ValueError("题目约定被破坏:不存在答案")

assert two_sum([2, 7, 11, 15], 9) == [0, 1]
assert two_sum([3, 3], 6) == [0, 1]
assert two_sum([-4, 9, 1], 5) == [0, 1]

不变量是:进入第 i 轮检查时,seen 含有下标 0 到 i-1 的值和下标。找到 need 时,旧下标一定不同于 i;若没找到,加入当前值后不变量继续成立。每个元素只处理一次,平均时间 O(n),额外空间 O(n)

易错纠正与当堂练习

  • 返回 [2,7] 是返回数值,不是下标。
  • 不能默认元素为正数;滑动窗口在含负数时没有这里需要的单调性。
  • 重复值不是重复使用同一元素,关键看下标是否不同。

请把题目改成“可能无解,返回空数组;可能有多组,返回任意一组”,先改规格,再改函数。随后测试空数组、[3,3]、含负数和无解输入。只有测试与约定一致,代码才算完成。

下课预告

下一课会学习循环不变量:它不是写给阅卷人的装饰,而是解释“为什么每轮扫描后仍没有漏掉答案”的工具。

出口自检

合上正文后完成三项验收:一,用自己的话解释“从题意写出形式化规格”解决什么问题;二,闭卷写出状态定义、不变量、复杂度和至少三个边界测试,再运行代码核对;三,写出一个会使当前方法失效或答案改变的条件。随后打开正文逐项核对。任何一项说不清,就回到对应证据或步骤修正,而不是继续背结论。

Practice

本课练习

6

先独立作答再提交;编程题会在隔离沙箱中真实编译、运行并对拍。

1本课验收:从题意写出形式化规格 1

算法面试工况 487:主题为从题意写出形式化规格。给定一组满足题意的输入,要求输出唯一可复核的结果,并能指出不满足前提时的行为。候选解必须把输入域、输出契约和无解约定写清;随后给出维护条件及终止时推出结论的链条。

以下哪项审查结论符合这一课的严格要求?

登录 后答题可以领积分
2概念验收:从题意写出形式化规格 2

哪个是非空数组最大值的完整后置条件?

登录 后答题可以领积分
3错误诊断:从题意写出形式化规格 2

形式化一道要求“返回两数之和的原数组下标”的题目,规格中不可缺少哪组信息?

登录 后答题可以领积分
4代码实验:区间规格归一化 4

输入两个整数 a、b,输出区间左端点 min(a,b) 与右端点 max(a,b)。

使用 Python 3,从标准输入读取并写到标准输出。

登录 后答题可以领积分
5多选关卡:证明与复杂度 · 从题意写出形式化规格 3

围绕下面的课内任务,哪些做法属于合格验收?(选两项)

形式化一道数组题至少要写清哪四类信息?

多选题:必须选全正确项,漏选或多选均不得分。

登录 后答题可以领积分
6定量关卡:证明与复杂度 · 从题意写出形式化规格 3

一份完整数组题规格需写清输入、输出、边界约定、资源限制四类信息,共几类?

登录 后答题可以领积分