在算法刷题与工程建模中,我们经常会遇到求最优解、枚举可行方案类问题。很多初学者容易混淆动态规划、贪心、分治、回溯等算法,它们看起来都可以递归拆解问题,但底层约束、适用场景、决策逻辑截然不同。本文从核心思想、关键特征、判定方式、典型例题四个维度做统一对比,并对核心特征给出规范解释,方便理解与选用。
算法对比表
| 算法 | 核心思想 | 关键特征 | 典型判定一句话 | 典型题目 |
|---|---|---|---|---|
| 动态规划 DP | 将原问题拆解为子问题,缓存子问题最优解,通过状态转移方程由子问题最优推导更大问题最优 | 最优子结构 重叠子问题 无后效性 | 存在多条合法决策分支,需要复用前面子问题的最优结果,不能直接选眼前最大值 | 打家劫舍、01 背包、最长递增子序列 LIS、零钱兑换 |
| 贪心 Greedy | 每一步直接选择当前局部最优的选项,选择不可逆,不回溯、不尝试其他分支 | 最优子结构 无后效性 局部最优可推全局最优 | 可以证明每一步选当下最优,不会堵死后续更优方案,一条路走到头就能得到全局最优 | 分发饼干、跳跃游戏、区间调度(最多不重叠区间)、哈夫曼编码 |
| 分治 Divide & Conquer | 把原问题切分成若干规模更小、结构相同、互不重叠的子问题,独立求解子问题后,合并子问题答案得到原问题解 | 最优子结构 无后效性 子问题相互独立 | 问题可以切为完全独立的几块,子问题不会重复计算,算完合并结果即可 | 归并排序、快速排序、二叉树递归、最大子数组(分治版本) |
| 回溯(纯 DFS 暴力) | 深度优先遍历,尝试选择、递归深入、递归返回时撤销选择,遍历所有合法方案,可搭配剪枝减少无效搜索 | 枚举全部可行解 支持状态回退 | 需要找出所有满足条件的方案,或者在全部方案里找答案,需要试错 + 回退 | 全排列、子集、组合总和、N 皇后 |
| 记忆化搜索(自顶向下 DP) | 回溯搜索框架 + 备忘录缓存已经算出的子问题结果,避免重复递归计算,等价于自顶向下 DP | 最优子结构 重叠子问题 无后效性 | 递归求解会重复算同一个子问题,增加备忘录缓存结果,和迭代 DP 只是遍历顺序不同 | 斐波那契、爬楼梯、石子合并(区间 DP) |
| 朴素暴力枚举 | 无特殊策略,直接遍历全部输入组合,逐个校验约束条件,筛选符合要求的答案 | 枚举全部可行解 | 没有任何拆分、缓存、贪心策略,直接把所有可能性挨个校验 | 双层循环暴力两数之和、暴力枚举所有子数组 |
核心特征释义
1. 最优子结构
释义:原问题的全局最优解,可以由它的若干子问题的最优解通过转移、组合得到。想要得到大问题的最优解,只需要先求出规模更小的子问题的最优解。
DP、贪心、分治都具备这个特征;回溯、暴力枚举不以它作为前提,目标是找全部可行解,不需要用子最优拼接全局最优。 注意:仅有最优子结构不足以使用DP,还必须同时满足重叠子问题。
2. 重叠子问题
释义:递归拆解求解时,不同的递归分支会重复计算同一个子问题。
这是DP和分治最核心分界线:DP中子问题反复被调用,所以使用数组/备忘录缓存结果,节省重复计算开销;分治切割后的子问题互不相交,每个子问题只会计算一次,不需要缓存。贪心、纯回溯不利用该特征;记忆化搜索就是利用重叠子问题做缓存优化。
3. 无后效性
释义:某个子问题的状态一旦计算完成,取值就固定不变;后续的决策、后续更大规模的状态,不会反向修改已经算好的历史状态。过去的状态影响未来,未来不会改写过去。
DP、贪心、分治都要求满足无后效性;回溯天然破坏无后效性,递归返回时撤销选择、修改状态,也就是存在后效。很多题目原生带有后效性,可以重新设计状态定义消除后效性,才能使用DP。
4. 局部最优可推全局最优
释义:每一步做出当前视角最优的选择,该选择不会封锁后续所有更优路线;一系列局部最优选择累积之后,一定得到全局最优解。
这是贪心算法成立的硬性必要条件,也是刷题最容易踩坑的地方,该条件很难证明;一旦不满足,贪心直接失效,典型例子:打家劫舍。
5. 枚举全部可行解
释义:算法会遍历问题空间内所有符合约束条件的方案,再从中筛选答案。
回溯、朴素暴力枚举属于这类;DP、贪心、分治不会枚举全部方案,依靠策略直接拿到最优,主动舍弃大量分支。
6. 子问题相互独立
释义:拆分出来的多个子问题输入集合互不相交,求解A子问题完全不需要B子问题的结果,互相之间没有依赖。
这是分治的核心特征;DP的子问题互相依赖、存在重叠,不满足独立。
算法选择判定流程
- 需求是输出全部合法方案 → 回溯(可加剪枝)
- 只需要求最优解:
- 子问题大量重复计算 → DP(迭代DP / 记忆化搜索)
- 子问题互不重叠、相互独立 → 分治
- 能够证明局部最优一定导向全局最优 → 贪心
- 没有任何优化策略,直接遍历所有组合校验 → 朴素暴力枚举
补充说明
- 记忆化搜索本质属于DP,只是实现形式是自顶向下递归,和迭代DP只是遍历顺序差异;
- LIS贪心+二分版本:不是纯贪心,是贪心思想优化DP,底层状态依然满足DP三要素;
- 剪枝回溯只是减少无效枚举,本质仍然是回溯,没有改变"撤销选择、存在后效"的特点。
结尾小结
这几类算法不存在绝对优劣,核心是匹配问题本身的约束。贪心最简单,但证明门槛最高;DP适用范围更广,重点在于状态设计;分治适合独立子问题;回溯适合枚举方案。理解这几个核心特征,就可以从"凭感觉套模板"升级为"根据问题性质选择算法"。