前端进阶之旅前端进阶之旅
  • 基础篇HTML/CSS/JS 打底
  • 进阶篇原理与工程化
  • 高频篇面试最常问的那批
  • 精选篇按模块收敛的总结
  • 手写篇常考代码手写实现
  • 面经篇真实面试问题复盘
  • AI 篇NEWAI 时代的前端考点
  • 历年面经NEW按年份追踪真实考点
  • 每日一题每天一道,攒手感
  • 专项自测100 题快速查漏
  • 小程序题库小程序专项刷题
  • 算法题库NEW在线编码即时判题
  • 知识卡片NEW碎片时间过考点
  • 面试题大全常见问题解析
  • AI 答疑NEW随时提问,即时解析
  • AI 模拟面试NEW模拟真实面试 + 报告
  • AI 定制路线NEW按你的简历现排
  • AI 知识地图NEW串起全站知识点
  • 原理篇React / Vue 源码拆解
  • HTTP从报文一路讲到 HTTPS
  • 浏览器渲染、事件循环、进程
  • 计算机基础Linux、网络、操作系统
  • 设计模式23 种模式怎么用
  • Node学习指南从环境搭建到服务端
  • NPM工作流script、依赖与发布
  • Docker容器化部署上手
  • Canvas图形与动画实战
  • 前端系统进阶学习大型项目工程化
  • 前端综合文章长期沉淀的实践文
  • 思维导图知识点全景图
  • 学习路线按图索骥不跑偏
  • AI 热点NEWAI 每日动态
  • 公众号动态公众号历史文章
  • 博客动态站长的技术博客
  • 开发者导航常用工具与文档站
  • 基础篇HTML/CSS/JS 打底
  • 进阶篇原理与工程化
  • 高频篇面试最常问的那批
  • 精选篇按模块收敛的总结
  • 手写篇常考代码手写实现
  • 面经篇真实面试问题复盘
  • AI 篇NEWAI 时代的前端考点
  • 历年面经NEW按年份追踪真实考点
  • 每日一题每天一道,攒手感
  • 专项自测100 题快速查漏
  • 小程序题库小程序专项刷题
  • 算法题库NEW在线编码即时判题
  • 知识卡片NEW碎片时间过考点
  • 面试题大全常见问题解析
  • AI 答疑NEW随时提问,即时解析
  • AI 模拟面试NEW模拟真实面试 + 报告
  • AI 定制路线NEW按你的简历现排
  • AI 知识地图NEW串起全站知识点
  • 原理篇React / Vue 源码拆解
  • HTTP从报文一路讲到 HTTPS
  • 浏览器渲染、事件循环、进程
  • 计算机基础Linux、网络、操作系统
  • 设计模式23 种模式怎么用
  • Node学习指南从环境搭建到服务端
  • NPM工作流script、依赖与发布
  • Docker容器化部署上手
  • Canvas图形与动画实战
  • 前端系统进阶学习大型项目工程化
  • 前端综合文章长期沉淀的实践文
  • 思维导图知识点全景图
  • 学习路线按图索骥不跑偏
  • AI 热点NEWAI 每日动态
  • 公众号动态公众号历史文章
  • 博客动态站长的技术博客
  • 开发者导航常用工具与文档站
首页程序员面试题库动态规划 贪心算法 区别
算法算法动态规划

动态规划和贪心算法的决策方式有什么本质区别,为什么贪心在有些最优化问题上失效?

动态规划枚举并比较所有子问题解,保证全局最优;贪心每次选当前局部最佳,仅在满足最优子结构和贪心选择性质时正确,否则失效。

前端进阶之旅 · 一题精讲更新于 2026.09.05
算法#动态规划
先看核心答案读代码示例
理解线索

贪心选择 vs 动态求解

  1. 动态规划保存所有子问题最优解,比较转移
  2. 贪心只保留当前选择,不回溯
  3. 贪心选择性质局部最优能构成全局最优

贪心也需最优子结构,但可缺少重叠子问题。

核心回答

先记住这个答案

动态规划将问题分解为重叠子问题,记录每个状态并比较所有转移,避免重复计算,从而获得全局最优。贪心则每一步选择一个当前看来最好的方案,期望逐步构造出最终答案,它不保留备选状态,也不回溯比较。贪心正确需要问题具备贪心选择性质:局部最优的选择可以成为全局最优解的一部分。若此性质不成立,如找零面额非规范时,贪心会得到次优答案。判断方法:先验证最优子结构,再用交换论证或构造反例检验贪心选择是否安全。

  • 贪心是单路径选择,DP枚举状态比较
  • 贪心失效因缺少贪心选择性质
  • 验证贪心可构造反例或交换论证

核心机制对比

动态规划的核心是把问题定义为状态,转移方程合并所有可能决策,最终在状态集合中取最优。例如在硬币问题中,dp[i]存储金额i的最小硬币数,每个状态尝试所有面额更新。贪心则不在状态空间搜索,而是按照一个确定性规则每次挑一个硬币,例如面额降序取时可能立即固定选择,不做备选。

贪心之所以快是它把O(n*C)的状态扫描压缩成O(n)或O(m),但代价是必须验证每一步贪心选择不会妨碍未来。数学上,贪心通常要求一个全序的局部指标,并且该指标的可加性使余下问题独立。若缺少该性质,当前最佳会夺走更优的未来组合。

贪心 vs DP 找零JavaScript
function greedy(coins, amount) {
  let count = 0;
  let remaining = amount;
  for (let coin of [...coins].sort((a,b)=>b-a)) {
    while (remaining >= coin) {
      remaining -= coin;
      count++;
    }
  }
  return remaining === 0 ? count : -1;
}

function dpCoins(coins, amount) {
  const dp = new Array(amount+1).fill(Infinity);
  dp[0] = 0;
  for (let i = 1; i <= amount; i++) {
    for (let c of coins) {
      if (i-c >= 0) dp[i] = Math.min(dp[i], dp[i-c]+1);
    }
  }
  return dp[amount] === Infinity ? -1 : dp[amount];
}

const coins = [1,3,4];
const target = 6;
console.log('greedy:', greedy(coins, target));
console.log('dp:', dpCoins(coins, target));
查看输出与解释
greedy: 3
dp: 2

贪心固定先取4,剩余金额无法取3,被迫用1;DP枚举所有面额并保留每个金额的最小硬币数,因此发现3+3。输出显示贪心结果3,DP结果2。

一个找零钱反例

设硬币面额为1、3、4,要凑6元。贪心按最大面额优先:先取4,余2只能1+1,总数3枚(4+1+1)。但最优是3+3两枚。这里贪心选择4后,剩余2已无法用3,被迫用1。因为局部最大面额并没有为剩余金额保留更好的公约空间。

对这个例子做动态规划:dp[0]=0,dp[1]=1,dp[2]=2,dp[3]=1,dp[4]=1,dp[5]=2,dp[6]=2。它比较了取4继续到2(3枚)和取3到3(2枚)。可见只有枚举状态才能识别3+3比4+1+1更优。贪心一次决定无缘比较分支。

何时贪心有效与判断

贪心有效需要两个条件:一是问题具有最优子结构(全局最优包含局部最优子问题最优);二是贪心选择性质,即存在一种排序或规则使每次的选择都是最优前缀。典型如活动选择:按结束时间排序,最早结束的活动是对所有最优解都有益的选择。如果排序规则没有这一数学保证,立即失效,例如分数背包可贪心但0-1背包不能。

工程师判断时可以采取两个步骤:先尝试将决策表达式写成递归最优化,再对每种排序规则做交换论证,证明交换任意两个选择不会变差。更实用的是在真实规模内跑随机数据生成,把贪心结果与穷举或DP解对比,若存在差例则放弃贪心。但测试只能证伪不能证实,缺少证明时安全选择动态规划。

回答前,多想一步

容易答错的地方

贪心问题都能用动态规划解决
并非所有贪心问题都适合用动态规划高效求解。DP依赖可枚举的状态和可记忆化的子问题;部分贪心问题虽可能写出递推式,但状态空间可能呈指数级或缺乏重叠子问题,例如哈夫曼编码若强行定义区间或子集型状态,计算量远大于贪心策略。因此不能无条件断言所有贪心问题都能用DP解决。
贪心失效是因为没有最优子结构
贪心失效往往不是缺少最优子结构。找零面额1,3,4时金额6的最优解包含金额3的最优解(1枚3),故最优子结构满足,但局部选4不是全局最优的一部分。失败点是贪心选择性质不成立。
试着用自己的话回答

面试官还会怎么问?

如何证明贪心策略的正确性?

常用交换论证:任取最优解,把贪心选的第一个选择与最优解中对应位置交换,证明不劣;随后对剩余子问题递归应用。也可用拟阵理论,或证明每一步的排序指标构成一个线性可加函数。

动态规划一定比贪心慢吗?

通常DP需要遍历状态空间,若状态数O(n)则可能相近,但大多数问题的DP复杂度高于贪心。然而动态规划提供正确性保证,贪心需额外证明。实践中若贪心易证,则优先使用,否则保守选DP。

有没有典型的贪心失效而DP成功的例子?

0-1背包、非规范硬币找零、加权区间调度等。这些都有重叠子问题,DP可解且能给出精确最优值;而贪心按单一指标选则可能漏掉更优组合。

从一道题,走向一组知识

把知识连起来

搜索与排序

写二分查找时用左闭右闭和左闭右开区间有什么本质区别?

继续了解 二分查找 循环不变量 边界写法,补充本题涉及的 算法 相关知识。

图算法

为什么 BFS 能在无权图中求出单源最短路径?

继续了解 BFS 无权图 最短路,补充本题涉及的 算法 相关知识。

参考资料

  • Introduction to Dynamic Programming¶

示例用于理解所注明的运行环境与边界;延伸学习可结合原文中的更多案例。

本题目录
  1. 先记住这个答案
  2. 核心机制对比
  3. 一个找零钱反例
  4. 何时贪心有效与判断
  5. 容易答错的地方
  6. 面试官还会怎么问
  7. 把知识连起来
读懂,再试着讲出来

先看核心答案,再读代码。最后展开追问,检查自己有没有遗漏边界。

试着回答追问
浏览全部面试题理解原理,也关注真实的使用场景。回到顶部 ↑