学习指南 →

· Albion Gateway College

算法复杂度练习:先数操作,再判断输入翻倍的影响

从具体操作次数推导 Big O,比较独立与依赖的嵌套循环,并用输入翻倍检验线性、平方与对数增长。

先定义规模与成本模型

复杂度分析回答的是输入增长时,工作量怎样变化。首先说明 n 代表什么:数组元素个数、图的顶点数,还是整数的位数。若任务同时接收两张长度分别为 n 与 m 的列表,不应未经解释就把它们都叫作 n。接着选一个可以数清楚的基本操作,例如比较两个元素一次。

本文以循环中执行一次标记操作为一次成本,假设索引和小整数运算的成本固定,循环不中途退出。这个约定让我们先比较算法结构,暂不把打印、文件读取、网络请求混进计数。运行时间还受机器、解释器及数据内容影响,因此一次计时不能直接等同于复杂度结论。

把线性计数与渐近符号分开

设一个程序扫描 n 个元素,每个元素做三次标记,最后额外做两次,操作总数为 3*n+2。n 为 4、8、16 时,次数分别是 14、26、50。系数与固定开销影响实际工作量;渐近分析关注规模足够大后的增长类型,所以这个计数属于线性增长。

Big O 描述渐近上界,不是精确次数,也不自动表示最坏情况。严格地说,上述计数既是 O(n),也是较松的 O(n²);当要表达紧确增长级别时,可使用 Θ(n)。最好先写“这里分析无提前退出的完整扫描”,再给出紧的界,而不是把“O”误读成固定耗时。

独立的两层循环:相乘有明确前提

现在让外层 i 取 range(n),每一轮内层 j 都取完整的 range(n)。每个 i 对应 n 个 j,共执行 n*n 次标记。可在 Python 3 输入 n = 5,再另行输入 print(sum(1 for i in range(n) for j in range(n))),结果应为 25。此处生成式只是简洁的计数工具。

如果内层改为 range(m),总数是 n*m,不能在不知道 m 与 n 的关系时写成 n²。若内层始终只执行固定的五次,总数则是 5*n,即线性增长。因此“有两个循环,所以平方复杂度”不是可靠推理;真正需要检查的是每轮内层到底做多少工作。

依赖外层变量时,先列出一串次数

把内层改成 range(i),而外层仍为 range(n)。当 n=5,内层次数依次是 0、1、2、3、4,总共 10 次。可用 print(sum(1 for i in range(5) for j in range(i))) 核验。一般情况下,总数是 n*(n-1)/2,仍是平方级,但并不是 n² 次。

如果分析的是无序元素对,这个三角形范围恰好避免比较自己,也避免把同一对反向再比较一次。n=1 时应为零,能检验是否误写了 range(i+1)。先列出小例子的每行长度,再把它们相加,通常比凭代码外观猜复杂度更稳妥;省掉一半工作并没有改变平方增长级别。

不是每个依赖循环都保持平方增长

再看一个不同结构:令 k 从 1 开始,每轮执行 k 次标记,随后把 k 乘 2,只要 k 小于 n 就继续。n=16 时,各轮工作量是 1、2、4、8,总和为 15。外层只有四轮,但内层长度不同,不能把“最大内层长度”直接当成每轮长度。

对于二的幂 n,这个总和为 n-1;对一般正整数 n,总和也小于 2*n,因此整体是线性级。与之对照,如果外层同样按倍增方式推进,但每轮内层始终做 n 次,才得到 n 乘对数级的工作量。关键不是机械地相乘两个最大次数,而是计算真实的总和。

输入翻倍可以检验预测,不能代替推导

对三角形计数,n=4、8、16 时分别得到 6、28、120;相邻比值约为 4.67 和 4.29,随着规模增长趋近 4。有限规模的比值不必恰好等于 4,因为表达式还带有较低阶项。对于 n²,翻倍正好变为四倍;对于 n,翻倍是两倍。

对数增长则不同:规模从二的 k 次幂增至二的 k+1 次幂,工作量通常只多一个同类步骤,不能说“输入翻倍,耗时也翻倍”。若实际测量,应保持输入类别、运行环境和计时范围一致,重复测试并报告波动。小数据的启动成本与噪声可能掩盖增长趋势;复杂度也不保证在任何小规模上都更快。

自练与可复用的分析记录

练习一:外层 range(n),内层 range(3),之后另做一次长度为 n 的扫描。总数是 3*n+n=4*n,属于线性级。练习二:外层 range(n),内层 range(i+1)。总数是 n*(n+1)/2;n 为 4、8 时分别为 10、36,属于平方级。先写预测,再用计数器或生成式验证。

练习三:搜索列表,找到目标便立即返回。目标位于首项与完全不存在时,比较次数不同;应分别说明最好和最坏输入,不能从首项命中的样本推出所有情况都只需一次。最后保留一份分析记录:规模定义、成本单位、输入情形、次数表达式、渐近结论和两个小规模检查。这个过程比背诵循环层数更容易迁移到新的题目。

参考资料

下一步

讨论复杂度时,带上你选定的基本操作、计数过程及测试规模,比只提供一个 Big O 答案更便于定位问题。

继续阅读

学院在线咨询

欢迎咨询

你好,欢迎咨询!你是学生、招生代理、求职者,还是想申请成为导师?请告诉我你的咨询方向。

[email protected]