news 2026/5/11 10:43:37

算法基础(十二)——主方法:快速求解常见递归式

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
算法基础(十二)——主方法:快速求解常见递归式

1. 定位导航

分治算法经常会产生递归式。

例如:

T(n) = 2T(n/2) + n T(n) = 2T(n/2) + 1 T(n) = 2T(n/2) + n²

这些递归式看起来相似,但结果可能完全不同:

O(n log n) O(n) O(n²)

主方法就是一种快速判断工具。

它不需要每次完整画递归树,而是通过比较两个关键量来判断结果。

2. 概念术语

术语含义举例
主方法求解一类分治递归式的快速方法T(n)=aT(n/b)+f(n)
a子问题个数2T(n/2)中的2
b子问题规模缩小倍数T(n/2)中的2
f(n)分解与合并的额外成本归并排序合并成本n
基准项递归展开形成的叶子侧规模n^(log_b a)
情况 1f(n) 比基准项小递归成本主导
情况 2f(n) 与基准项同级每层成本相近
情况 3f(n) 比基准项大合并成本主导

关键澄清:

  1. 主方法不是所有递归式都能用。
  2. 它主要适用于T(n)=aT(n/b)+f(n)这种形式。
  3. 判断关键是比较f(n)n^(log_b a)
  4. 不要只看abf(n)经常决定最终结果。

3. 主方法解决哪类问题

主方法适用于形如:

T ( n ) = a T ( n / b ) + f ( n ) T(n) = aT(n/b) + f(n)T(n)=aT(n/b)+f(n)

的递归式。

其中:

  • a表示子问题个数;
  • n/b表示每个子问题的规模;
  • f(n)表示除了递归子问题之外,本层额外做的工作。

比如归并排序:

T ( n ) = 2 T ( n / 2 ) + n T(n) = 2T(n/2) + nT(n)=2T(n/2)+n

对应关系是:

部分含义
a2拆成两个子问题
b2每个子问题规模是原来一半
f(n)n合并两个有序数组需要线性时间

4. 核心比较对象:f(n) 与 n^(log_b a)

主方法最关键的一步是计算:

n log ⁡ b a n^{\log_b a}nlogba

这个量可以理解为递归树中“子问题扩张出来的基准增长”。

然后比较:

f(n) 和 n^(log_b a)

谁更强。

以归并排序为例:

T ( n ) = 2 T ( n / 2 ) + n T(n) = 2T(n/2) + nT(n)=2T(n/2)+n

这里:

a = 2 , b = 2 a = 2,\quad b = 2a=2,b=2

所以:

n log ⁡ b a = n log ⁡ 2 2 = n n^{\log_b a} = n^{\log_2 2} = nnlogba=nlog22=n

而:

f ( n ) = n f(n) = nf(n)=n

两者同级,所以属于情况 2。

结果是:

T ( n ) = Θ ( n log ⁡ n ) T(n) = \Theta(n \log n)T(n)=Θ(nlogn)

5. 主方法的三种情况

主方法可以分成三种情况。

5.1 情况 1:f(n) 更小

如果:

f ( n ) f(n)f(n)

比:

n log ⁡ b a n^{\log_b a}nlogba

小一个多项式级别,那么递归成本主导。

结果是:

T ( n ) = Θ ( n log ⁡ b a ) T(n) = \Theta(n^{\log_b a})T(n)=Θ(nlogba)

直觉:

越往下递归,子问题数量增长带来的成本更重要。

5.2 情况 2:f(n) 与基准项同级

如果:

f ( n ) = Θ ( n log ⁡ b a ) f(n) = \Theta(n^{\log_b a})f(n)=Θ(nlogba)

那么每一层贡献差不多。

结果是:

T ( n ) = Θ ( n log ⁡ b a log ⁡ n ) T(n) = \Theta(n^{\log_b a} \log n)T(n)=Θ(nlogbalogn)

直觉:

每一层都差不多,总共约 log n 层,所以多乘一个 log n。

5.3 情况 3:f(n) 更大

如果:

f ( n ) f(n)f(n)

比:

n log ⁡ b a n^{\log_b a}nlogba

大一个多项式级别,并且满足一定的正则条件,那么本层额外工作主导。

结果是:

T ( n ) = Θ ( f ( n ) ) T(n) = \Theta(f(n))T(n)=Θ(f(n))

直觉:

上层合并成本已经足够大,递归子问题反而不是主导。

6. 动态推演:三种情况如何判断

下面用动态图观察三种关系。

可以这样理解:

  • 情况 1:f(n)比基准项更小,递归展开更重要;
  • 情况 2:f(n)和基准项同级,每层成本接近;
  • 情况 3:f(n)比基准项更大,当前层工作更重要。

7. 典型例子

7.1 例子一:T(n)=2T(n/2)+n

这里:

a = 2 , b = 2 , f ( n ) = n a=2,\quad b=2,\quad f(n)=na=2,b=2,f(n)=n

基准项:

n log ⁡ 2 2 = n n^{\log_2 2}=nnlog22=n

f(n)和基准项同级,属于情况 2。

所以:

T ( n ) = Θ ( n log ⁡ n ) T(n)=\Theta(n\log n)T(n)=Θ(nlogn)

7.2 例子二:T(n)=2T(n/2)+1

这里:

a = 2 , b = 2 , f ( n ) = 1 a=2,\quad b=2,\quad f(n)=1a=2,b=2,f(n)=1

基准项:

n log ⁡ 2 2 = n n^{\log_2 2}=nnlog22=n

f(n)比基准项小,属于情况 1。

所以:

T ( n ) = Θ ( n ) T(n)=\Theta(n)T(n)=Θ(n)

7.3 例子三:T(n)=2T(n/2)+n²

这里:

a = 2 , b = 2 , f ( n ) = n 2 a=2,\quad b=2,\quad f(n)=n^2a=2,b=2,f(n)=n2

基准项:

n log ⁡ 2 2 = n n^{\log_2 2}=nnlog22=n

f(n)比基准项大,属于情况 3。

所以:

T ( n ) = Θ ( n 2 ) T(n)=\Theta(n^2)T(n)=Θ(n2)

8. 判断流程

使用主方法时,可以按照下面流程来。

第一步:确认递归式形式

先确认是否形如:

T ( n ) = a T ( n / b ) + f ( n ) T(n)=aT(n/b)+f(n)T(n)=aT(n/b)+f(n)

如果形式不匹配,不要硬套。

第二步:计算基准项

计算:

n log ⁡ b a n^{\log_b a}nlogba

第三步:比较强弱

比较:

f(n) 与 n^(log_b a)

谁更大、谁更小,或者是否同级。

第四步:套用三种情况

根据比较结果,选择情况 1、情况 2 或情况 3。

9. 代码实践:自动套用简单主方法

下面写一个简单的 Python 小工具,只处理f(n)=n^k这种常见形式。

importmathdefmaster_method(a,b,k):""" 处理递归式: T(n) = aT(n/b) + n^k 参数: a: 子问题个数 b: 子问题缩小倍数 k: f(n)=n^k 中的 k """critical=math.log(a,b)print(f"a ={a}, b ={b}, f(n) = n^{k}")print(f"基准指数 log_b(a) ={critical:.4f}")ifk<critical:print("情况 1:f(n) 更小")print(f"T(n) = Θ(n^{critical:.4f})")elifabs(k-critical)<1e-9:print("情况 2:f(n) 与基准项同级")print(f"T(n) = Θ(n^{critical:.4f}log n)")else:print("情况 3:f(n) 更大")print(f"T(n) = Θ(n^{k})")master_method(2,2,1)print()master_method(2,2,0)print()master_method(2,2,2)

输出示例:

a = 2, b = 2, f(n) = n^1 基准指数 log_b(a) = 1.0000 情况 2:f(n) 与基准项同级 T(n) = Θ(n^1.0000 log n) a = 2, b = 2, f(n) = n^0 基准指数 log_b(a) = 1.0000 情况 1:f(n) 更小 T(n) = Θ(n^1.0000) a = 2, b = 2, f(n) = n^2 基准指数 log_b(a) = 1.0000 情况 3:f(n) 更大 T(n) = Θ(n^2)

这个工具不是完整的数学证明器,但可以帮助快速建立判断直觉。

10. 常见误区

误区一:看到递归式就硬套主方法

不是所有递归式都能直接套。

例如:

T(n)=T(n-1)+n

它不是aT(n/b)+f(n)形式,就不适合直接用这个版本的主方法。

误区二:算错 log_b a

主方法的核心基准项是:

n log ⁡ b a n^{\log_b a}nlogba

如果这里算错,后面判断都会错。

误区三:忘记情况 2 里的 log n

当:

f ( n ) = Θ ( n log ⁡ b a ) f(n)=\Theta(n^{\log_b a})f(n)=Θ(nlogba)

结果不是简单的:

Θ ( n log ⁡ b a ) \Theta(n^{\log_b a})Θ(nlogba)

而是:

Θ ( n log ⁡ b a log ⁡ n ) \Theta(n^{\log_b a}\log n)Θ(nlogbalogn)

误区四:只凭直觉比较大小

比较f(n)和基准项时,要看增长量级,不是看某个小规模下的数值。

11. 现代延伸

主方法不仅用于排序,也常用于分析很多分治或递归系统。

场景可能出现的递归式
归并排序T(n)=2T(n/2)+n
二分查找T(n)=T(n/2)+1
分治统计T(n)=2T(n/2)+n
分块计算T(n)=aT(n/b)+f(n)
并行归约T(n)=2T(n/2)+1
多路分治T(n)=kT(n/k)+n

工程里很多“拆分—递归处理—合并”的流程,都可以先写出递归式,再用类似方法估算增长趋势。

比如大文件分块处理、分布式聚合、多级归并、并行任务树,都可以借助这种思路快速判断瓶颈来自哪里。

12. 思考题

  1. 主方法适用于哪类递归式?
  2. T(n)=2T(n/2)+n为什么是情况 2?
  3. T(n)=2T(n/2)+1为什么是情况 1?
  4. T(n)=2T(n/2)+n²为什么是情况 3?
  5. 为什么情况 2 的结果要多乘一个log n
  6. T(n)=3T(n/3)+n的复杂度是多少?

13. 本篇小结

本篇讲清楚了主方法。

核心结论是:

  • 主方法用于快速求解T(n)=aT(n/b)+f(n)类型的递归式;
  • a表示子问题个数;
  • b表示子问题规模缩小倍数;
  • f(n)表示本层额外工作;
  • 核心比较对象是f(n)n^(log_b a)
  • 情况 1:f(n)更小,结果看基准项;
  • 情况 2:两者同级,结果多乘一个log n
  • 情况 3:f(n)更大,结果看f(n)
  • 使用前要先确认递归式形式是否匹配。

主方法可以理解成递归树分析的快捷版。

递归树帮你看懂原因,主方法帮你快速得到结果。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/11 10:43:06

智能网联时代的分心驾驶:技术悖论、工程困境与系统化安全框架

1. 项目概述&#xff1a;一个被忽视的致命悖论 作为一名在汽车电子和智能网联领域摸爬滚打了十几年的工程师&#xff0c;我见过太多关于“未来出行”的炫酷概念和激动人心的技术路线图。从早期的车载信息娱乐系统&#xff0c;到后来的高级驾驶辅助系统&#xff0c;再到如今如火…

作者头像 李华
网站建设 2026/5/11 10:43:03

OpenVSP参数化飞机设计:从几何退化到气动优化的技术突破

OpenVSP参数化飞机设计&#xff1a;从几何退化到气动优化的技术突破 【免费下载链接】OpenVSP A parametric aircraft geometry tool 项目地址: https://gitcode.com/gh_mirrors/ope/OpenVSP 传统飞机设计面临着一个核心矛盾&#xff1a;几何模型的精确性与计算效率之间…

作者头像 李华
网站建设 2026/5/11 10:42:25

如何高效管理微信社交网络:微信工具箱终极使用指南

如何高效管理微信社交网络&#xff1a;微信工具箱终极使用指南 【免费下载链接】wechat-toolbox WeChat toolbox&#xff08;微信工具箱&#xff09; 项目地址: https://gitcode.com/gh_mirrors/we/wechat-toolbox 微信工具箱&#xff08;wechat-toolbox&#xff09;是一…

作者头像 李华
网站建设 2026/5/11 10:37:43

ComfyUI-Manager终极性能优化指南:让AI工作流流畅如飞

ComfyUI-Manager终极性能优化指南&#xff1a;让AI工作流流畅如飞 【免费下载链接】ComfyUI-Manager ComfyUI-Manager is an extension designed to enhance the usability of ComfyUI. It offers management functions to install, remove, disable, and enable various custo…

作者头像 李华
网站建设 2026/5/11 10:37:42

AcceRL框架:异步强化学习在VLA模型中的高效实现

1. AcceRL框架概述AcceRL是一个专为大规模视觉语言动作&#xff08;VLA&#xff09;模型设计的异步强化学习框架。这个框架的核心创新在于其可训练且即插即用的世界模型模块&#xff0c;通过高保真的想象rollouts显著提升了样本效率。我在实际部署中发现&#xff0c;这种设计让…

作者头像 李华
网站建设 2026/5/11 10:32:23

基于MCP协议构建YouTube AI助手:架构、部署与实战指南

1. 项目概述&#xff1a;一个连接YouTube与AI的“翻译官”最近在折腾AI应用开发&#xff0c;特别是想让大语言模型&#xff08;LLM&#xff09;能直接“看懂”和“操作”YouTube&#xff0c;比如让它帮我总结视频内容、查找特定主题的视频&#xff0c;甚至管理我的播放列表。要…

作者头像 李华