DEV Community

Woody
Woody

Posted on

about Greedy 贪心算法

好问题 👍,我给你系统讲一下 Greedy(贪心)算法


🔑 什么是 Greedy 算法?

Greedy(贪心)算法是一种 逐步构建答案的算法思想

  • 在每一步,都选择当前看起来 最优的局部选择(局部最优解)
  • 希望通过一系列局部最优选择,最终得到 全局最优解

不回溯、不穷举,而是依赖“局部最优能推出整体最优”的前提。


📘 经典例子

  1. 找零钱问题
  • 面额:1, 5, 10, 20, 50, 100
  • 找 187 元 → 每次尽量用最大面额:100 → 50 → 20 → 10 → 5 → 1 → 1
  • 总共 7 张。 👉 因为这种货币体系是“规范化的”,贪心一定能得到最优解。
  1. 活动选择(区间调度)
  • 给一堆活动,每个活动有开始时间和结束时间。
  • 想选最多的活动且不能重叠。
  • 策略:按结束时间最早排序,每次选能参加的活动。 👉 这是贪心算法的经典应用。
  1. LeetCode 861. Score After Flipping Matrix
  • 思路:第一列必须全 1(局部最优保证整体更大),再逐列保证 1 比 0 多。 👉 就是贪心。

⚡ Greedy 适合解决的问题

Greedy 并不是万能的,适用场景一般有两个条件:

  1. 贪心选择性质 (Greedy Choice Property)
  • 全局最优解可以通过一系列局部最优选择得到。
  • 例子:区间调度、找零钱(规范货币体系)。
  1. 最优子结构 (Optimal Substructure)
  • 问题的最优解包含其子问题的最优解。
  • 例子:活动选择问题。

🚫 贪心不适合的情况

  • 如果全局最优解 ≠ 局部最优解累积。
  • 比如:0/1 背包问题

    • 物品价值和重量不同,不能拆分。
    • 如果总重量 10,选物品时不能简单贪心选“单位价值最大”的 → 可能错。
    • 这种问题要用 动态规划(DP)

✅ 总结

  • Greedy = 每一步都做当前最优的选择。
  • 适合 局部最优 = 全局最优 的问题。
  • 常见应用:找零钱、区间调度、哈夫曼编码、最小生成树(Prim/Kruskal)、Dijkstra 最短路。

好 👍,我给你整理一份 经典贪心算法题目清单,涵盖 LeetCode 和常见面试题,分门别类带上思路,方便你系统刷题。


🔥 经典贪心算法题目清单

1. 区间类(调度/覆盖/合并)

这类题目是贪心的“标配”,核心思想是:按某个顺序排序,再逐步选择

  • 435. Non-overlapping Intervals
    删除最少的区间,使剩下的区间互不重叠。
    👉 思路:按结束时间排序,每次尽量选结束早的。

  • 452. Minimum Number of Arrows to Burst Balloons
    区间射气球,最少需要几支箭。
    👉 思路:按区间右端点排序,一支箭能覆盖尽量多的气球。

  • 56. Merge Intervals
    合并重叠区间。
    👉 思路:按左端点排序,逐个合并。

  • 活动选择问题 (经典面试题)
    选最多不重叠活动,按结束时间排序贪心。


2. 数组/序列操作

  • 55. Jump Game
    判断能否跳到终点。
    👉 思路:维护最远能到达的位置,每一步尽量走最远。

  • 45. Jump Game II
    最少跳几次到终点。
    👉 思路:在当前覆盖范围内尽量扩展下一步最远。

  • 134. Gas Station
    找出能否绕一圈加油站。
    👉 思路:贪心地统计油量差,若能走一圈,从累积最低点后出发。

  • 376. Wiggle Subsequence
    最长摆动子序列。
    👉 思路:只要趋势发生变化(正负号变化),计数 +1。


3. 数字 / 二进制类


4. 字符串/调度类

  • 621. Task Scheduler
    CPU 调度任务,最小执行时间。
    👉 思路:优先执行频率最高的任务,空闲时插入其他。

  • 402. Remove K Digits
    删除 K 个数字得到最小数。
    👉 思路:用栈,每次保证栈单调递增,不行就弹出前面的。

  • 763. Partition Labels
    分割字符串,每段尽量大,使不同段的字符不重复。
    👉 思路:贪心地按字符最后出现位置来切割。


5. 图/树中的贪心

  • Prim / Kruskal 算法 → 最小生成树(MST)。
  • Dijkstra 算法 → 单源最短路。 👉 它们本质上就是贪心,每次选择当前最短的边/路径。

✅ 总结

贪心题常见套路:

  1. 排序(按结束时间 / 开始时间 / 右端点)
  2. 局部最优选择(选最大 / 最小 / 最多 / 最少)
  3. 可行性验证(能走通 / 能覆盖 / 能找零)

Top comments (0)