贪心算法

贪心算法

#resource / algorithm #type / concept #status / growing #algo / greedy

[!info] related notes 算法面试题型 MOC

贪心算法详解

贪心算法(Greedy Algorithm)是一种在每一步选择中都采取在当前状态下最好或最优(即最有利)的选择,从而希望导致结果是全局最好或最优的算法策略。

基本概念

贪心算法的核心思想是:局部最优导致全局最优

贪心算法的特点

  1. 局部最优选择:在每一步都做出当前看起来最佳的选择
  2. 不可回退:一旦做出选择,就不再改变
  3. 高效性:通常比其他算法(如动态规划)更高效
  4. 不保证全局最优:只在某些特定问题中能得到最优解

贪心算法的适用条件

贪心算法适用于满足以下两个条件的问题:

  1. 贪心选择性质:局部最优选择能导致全局最优解
  2. 最优子结构:问题的最优解包含其子问题的最优解

贪心算法的基本步骤

  1. 建立数学模型来描述问题
  2. 将问题分解为若干个子问题
  3. 对每个子问题求解,得到局部最优解
  4. 把子问题的解合并成原问题的一个解

贪心策略

  • 从最小/最大开始贪心,优先考虑最小/最大的数,从小到大/从大到小贪心。在此基础上,衍生出了反悔贪心。
  • 从最左/最右开始贪心,思考第一个数/最后一个数的贪心策略,把 n 个数的原问题转换成 n−1 个数(或更少)的子问题。

普通贪心

从最小/最大开始贪心

优先考虑最小/最大的数,从小到大/从大到小贪心。

如果答案与数组元素顺序无关,一般需要排序。排序后,可以遍历计算。

单序列配对

双序列配对

从最左/最右开始贪心

对于无法排序的题目,尝试从左到右/从右到左贪心。思考第一个数/最后一个数的贪心策略,把 n 个数的原问题转换成 n−1 个数(或更少)的子问题。

读者可以对比下面的题目和 动态规划题单 中的线性 DP、状态机 DP 的区别,思考什么情况下只能 DP 不能贪心,从而加深对「局部最优」和「全局最优」的理解。

先枚举,再贪心

枚举题目的其中一个变量,将其视作已知条件,然后在此基础上贪心。

也可以枚举答案,检查是否可以满足要求。(类似二分答案)

区间贪心

区间贪心有如下经典问题:

  • 不相交区间(单机器调度/活动安排):给定一些区间,从中选出尽量多的两两互不相交的区间。
  • 区间分组(任务调度/会议室):给定一些区间,把这些区间分成最少的组,使得每组内的区间互不相交。
  • 区间选点(射气球,Interval Stabbing):给定一些区间,在数轴上放置最少的点,使得每个区间都包含至少一个点。最少要放置多少个点?
  • 区间覆盖(灌溉花园):给定一些区间,从中选出尽量少的区间,覆盖一条指定线段 [s,t]。

一般来说,区间合并问题(2.5 节)是按左端点排序,其余大多数区间贪心是按右端点排序。请读者在做题后,仔细体会为什么要这样排序。

不相交区间

字符串贪心

字典序最小/最大 字典序的定义如下:

对于两个字符串 a 和 b,从左到右依次比较字符 a[i] 和 b[i] 的 ASCII 值的大小。 a[i]=b[i] 时,如果 a[i]<b[i],那么 a 的字典序更小,否则 b 的字典序更小。 如果没有出现 a[i]=b[i],则短的字符串字典序更小。 如果两个字符串的长度和内容均相同,那么两个字符串的字典序一样。 字典序的定义也可以推广到数组上,按照上述方法比较两个数组的字典序。

参考

分享丨【算法题单】贪心算法(基本贪心策略/反悔/区间/字典序/数学/思维/构造) - 讨论 - 力扣(LeetCode)

作者:灵茶山艾府 链接:https://leetcode.cn/discuss/post/g6KTKL/ 来源:力扣(LeetCode) 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

创建于 2025/1/1 更新于 2026/5/27