Skip to content

方法Method

分治法

施工中 · 内容逐步修订

Divide and conquer

把问题分成较小同类子问题,递归求解后合并结果的算法设计范式。

形式陈述 ​

分治算法把规模为 n 的实例分成若干严格更小的子实例,递归求解并合并结果。正确性通常按递归结构作强归纳证明;运行时间常满足

T(n)=∑iT(ni)+g(n).

这里 ni 是第 i 个实际求解的子实例规模,g(n) 包含拆分与合并的非递归工作。递推还须给出小规模基例,例如 T(0),T(1)=O(1);仅说规模变小不足以确定成本。

正确性证明分三步:基例直接正确,假设较小实例已正确求解,再证明这些答案足够合成原实例答案。

直觉

分治把实例拆成规模严格下降、结构相同且覆盖原问题的子问题,独立求解后再组合答案。效率取决于子问题是否平衡、是否大量重叠,以及合并需要多少工作。经典分治通常不复用重叠子问题。

分解树、子问题与结果合并
例子与边界

归并排序把数组均分、递归排序两半,再线性合并。例如 [4,1,3,2] 的两半分别递归得到 [1,4] 与 [2,3]。合并时比较两端当前首项:先输出 1,再输出 2、3,右侧耗尽后接上 4。每次选出的较小首项不大于两侧所有剩余元素,所以输出前缀一直有序;这一不变量才是“合并正确”的理由。

每个元素在一次合并中仅被取走一次,故合并成本为 Θ(n)。对 n 为二的幂,递归式 T(n)=2T(n/2)+Θ(n) 的每层总工作为 Θ(n),共有 Θ(log⁡n) 层,得到 Θ(nlog⁡n);一般规模用上下取整划分,结论不变。二分搜索只保留一半候选,另一半根本不递归,因此 T(n)=T(n/2)+O(1) 得 O(log⁡n)。拆出了两半不代表一定有两个递归调用。

快速排序的子问题大小依赖枢轴,若枢轴总取到极端值,会形成 T(n)=T(n−1)+Θ(n) 的二次退化,说明“递归减小”不等于“平衡分治”,不能机械套用平衡分割递推。若子问题高度重叠,如朴素 Fibonacci 递归,记忆化比重复分治更合适。

推论与应用

分治用于排序、几何、FFT 与选择;平面最近点对展示了“递归解两侧 + packing 证明线性合并”的几何版本。折半搜索把指数候选分成两半并在中间匹配,将典型 2n 枚举改成约 2n/2 的时间—空间权衡;它仍是 exact exponential 算法,不因“折半”变成多项式。

同一递归图像还能服务不同模型。对数方法动态化把静态结构按二进制块合并,以重建换取摊还更新;缓存无关模型通过递归布局在未知 B,M 下控制块传输;并行算法模型把相互独立的子问题同时执行,并分别分析工作与深度。这些成本可写成递归关系,再用主定理或递归树分析;动态规划进一步处理子问题重叠带来的重复计算。

参考资料
  • Thomas H. Cormen, Charles E. Leiserson, Ronald L. Rivest, and Clifford Stein, Introduction to Algorithms, 4th ed., MIT Press, 2022, Chapter 4:分治与递推分析。
  • Jon Kleinberg and Éva Tardos, Algorithm Design, Pearson, 2005, Chapter 5:分治算法。
关系图谱18 个相邻概念 · 2 类关系

拖动节点调整位置。

显示关系

显示:依赖

  1. 前置三跳
  2. 前置二跳
  3. 前置一跳
  4. 当前条目
  5. 后续一跳
  6. 后续二跳
  7. 后续三跳
文字版关系按与当前条目的最短距离分组
类型化关系