Algorithm Design · Lecture 1-1

什么是算法?What Is an Algorithm?

在写下任何一行代码之前,先问一个看似简单、其实很挑剔的问题:一串指令,凭什么能被称作"算法"? 这一课我们用两个"冒牌货"来锤炼直觉,再拆掉第一个真算法。

Ke Chen · May 19, 2026 中英双语 可交互
向下滚动开始 · scroll to begin
01

定义 / The Definition

先把定义摆上桌。它读起来有点干,但每一个词都在"卡人"——我们随后会用反例逐个验证。

算法 (Algorithm):一个 有限的 (finite)无歧义的 (unambiguous)逐步的 (step-by-step) 指令集合,用来解决某个问题

↑ 三种颜色对应三根"支柱"。点开下面每一根看它到底在要求什么。

记住这个判据:"有限 · 无歧义 · 逐步解决问题",三者缺一不可。下面两个例子,各自砸掉其中一根支柱——看你能不能抓到是哪一根。

02

反例一:长生配方 / Not an Algorithm

出自 Ryan North 的《How to Take Over the World》。要成为超级反派,先得永生——他"贴心"地给了三步。

Not an algorithm

如何实现永生 · How to Achieve Immortality

  1. 变得极其富有(详见第五章)
    become extremely wealthy
  2. 停止衰老
    stop aging
  3. 避免任何意外或被谋杀,你就能永远活着
    avoid accidents / being murdered
它砸掉了哪一根支柱?Which pillar does it break?

关键在第二步"停止衰老"。它读起来像一条指令,但今天地球上没有任何人知道该怎么做——它不是一条明确、可执行的步骤。所以整份配方违反了unambiguous。就算第一步能"见第五章"补齐细节,第二步依然让整件事停留在愿望,而不是算法。

03

反例二:Collatz 猜想 / The 3n+1 Trap

这次每一步都清清楚楚、毫无歧义——问题出在别的地方。先玩一玩这个数字游戏。

Collatz 猜想(又叫 3n+1 猜想):从任意正整数 n 出发,反复执行——

  • 若 n 是奇数 (odd):n ← 3n + 1
  • 若 n 是偶数 (even):n ← n / 2

猜想断言:无论从哪个正整数开始,最终都会掉回 1。 一个小学生都能看懂的规则——却是当今最顶尖数学家都无法证明的难题。先亲手试试它有多"跳":

互动实验室 · Collatz Simulator
试试: 6 27 ✨ 97 871 6171
起点 START
步数 STEPS
峰值 PEAK
终点 END

注意:27 只是个小数字,却要跳 111 步、冲到 9232 才落地。轨迹毫无规律——这正是它难被证明的原因。

既然数学家搞不定,那我们计算机科学家干脆写个程序:暴力搜索一个反例(一个永远回不到 1 的数)。伪代码如下——每一行你都能翻译成任意语言,完全无歧义:

// 输出:3n+1 猜想的最小反例(如果存在)
CollatzCounterexample()
  n  2
  while true do                        // ← 红旗:无限循环
    current  n
    while current > 1 do
      if current % 2 == 0 then current  current / 2
      else current  3 * current + 1
      if current == n then return n   // 找到反例
    n  n + 1
这段代码无歧义,那它砸掉了哪一根支柱?Which pillar breaks now?

祸首是外层的 while true。它的潜台词是:"还没找到反例?继续找。" 但——没人知道反例是否存在。如果猜想是对的(反例不存在),这个循环就永远停不下来,违反了 finite

连接:停机问题 · The Halting Problem 存在一个已被证明的结论:不存在一个通用方法,能判断任意程序对任意输入是否会停机 (terminate)。 所以判断"会不会停"不能外包给某个万能检查器——身为算法的设计者,证明你的算法一定会在有限步内停止,是你自己的责任

留给你的练习:内层 while 其实也有隐患。如果某个 current 掉进一个不含 1 的循环,内层同样会卡死——而"这种循环不存在"恰恰是 Collatz 猜想尚未排除的另一半。

04

你早就在用算法 / You Already Know Many

算法不是屏幕里才有的东西。它古老、日常,且无处不在。

  • 加减乘除 (arithmetic) —— 你小学学的竖式,是古人发明的算法,每一步都有限、无歧义。
  • 用现金找零 (making change) —— "先给大面额、再补小面额"就是一套贪心 (greedy) 流程。
  • 配对袜子 (sorting socks) —— 从洗衣篮里两两配对,就是一次排序。甚至有正经论文:Defant & Kravitz, "Foot-sorting for socks", arXiv 2022,研究只用一只脚怎么排。
洞见 · The point 你今天看到的几乎一切——包括你正在用的 AI 工具——本质上都是算法。作为 CS(或相关专业)的人,你要能看懂它、判断它对不对、并决定何时该用它。这门课就是练这个。
05

为什么要学? / Why Study Algorithms?

除了"为了毕业"这个诚实的理由之外——

  • 计算是理解世界的基础:社交网络、大脑、黑洞、演化……都能用计算的视角看。
  • 分析正确性与资源消耗:一个方案对不对、要花多少时间/空间。
  • 衡量可行性:哪些问题能高效解决,哪些不能 —— 这就通向 NP-completeness
  • 面试:截至 2026 年 5 月,即便 AI 工具突飞猛进,大厂技术面依然在考算法。
  • 纯粹好玩 🎈

学期末你会摸到人类知识的边界。所有问题大致可以分成三块——点开看每一块:

高效可解

efficiently solvable
我们已经知道又快又对的算法。本课的大部分内容都在这里:排序、搜索、图算法、动态规划……

无人知晓

no efficient solution known
没人知道能不能高效解决,也没人证明不能。NP-complete 问题住在这里。本课结尾会讲这条边界。

证明不可能

provably impossible
已被严格证明无法用算法解决(比如停机问题)。这一块要到"计算理论 (theory of computation)"课才展开。
← 更容易NP-completeness 划这条线更难 →
06

分析一个算法的三问 / Three Questions

面对任何算法,我们永远按这个顺序问三个问题。顺序不能乱。

1

正确性

Correctness

每一个合法输入,它每次都给出正确答案吗?

2

复杂度

Complexity — time & space

它高效吗?跑得快不快(时间 time)、占内存多不多(空间 space)?

3

能更好吗?

Can we do better?

有没有更快、更省、更优雅的做法?

为什么顺序不能颠倒? 打开下面的开关,假装我们先去问"复杂度"——

尝试跳过正确性,直接问复杂度
现实里还有别的考量 鲁棒性 (robustness)、能耗、cache locality(要用的数据是否已在缓存里)、模块化、维护成本…… 在工业界都极其重要,但超出本课范围。这三问已经够我们走很远了。
07

第一个真算法:LinearSearch / Linear Search

终于是个货真价实的算法。任务:在数组里找一个元素,返回它最后一次出现的位置。

Input:数组 A[1..n],以及要查找的 key k
Outputk 在 A 中最后一次出现的下标;找不到则返回 −1

LinearSearch(A[1..n], k)
  i  n                // 从最后一个元素开始
  while i ≥ 1 do
    if A[i] == k then
      return i         // 往回扫,第一个命中的就是"最后出现"
    i  i − 1
  return1           // 扫完都没找到

留意一个巧思:它从后往前扫。因为要的是"最后一次出现",从末尾倒着走,第一个撞上的匹配就一定是最后那个。下面动手跑一遍:

互动实验室 · Linear Search Visualizer
要找的 key:
选一个 key,然后点"单步"看它怎么倒着扫。
① 正确性 · Correctness 论证只需一句话:我们从末尾开始,逐个检查每个元素。所以只要 k 真的在数组里,就不可能被漏掉(必然会被逐个扫到);如果它不在,就会一路扫到头、正确返回 −1。✔ 算法正确。
② 复杂度 · Complexity —— 下回分解 "它对"我们已经确认了。那"它有多快"?最好情况下 k 就在末尾(1 次比较搞定);最坏情况要扫遍全部 n 个元素。要把"多快"说清楚、说严谨,我们需要先建立一整套分析工具(渐进记号 Big-O 等)——那是下一课的主角。
08

随堂小测 / Quick Check

无限次尝试、零压力。只是检验一下理解。

Q1. 下面哪一项不是"算法"三条判据之一?
Q2. 一个含 while true 的程序,最需要担心它违反哪条判据?
Q3. 分析算法的三问,正确顺序是?
Q4. LinearSearch 为什么从后往前扫?