贪心

刷题之贪心算法

Posted by BX on Sat, May 3, 2025

贪心算法

🧠 一、贪心的核心定义

贪心算法是一种在每一步都做出局部最优选择,最终期望获得全局最优解的方法。

使用前提:
必须满足「局部最优 = 全局最优」,否则贪心可能不是正确解法。

🔍 二、判断是否可以贪心的典型信号

判断信号说明
✅ 排序后有策略可选按区间左/右/结束时间排序、按字典序等
✅ 选择之间互不影响子问题没有依赖,不选一个不会影响后续
✅ 无需回溯历史当前选完之后无需回头
✅ 问题目标是「最小/最大/能否/最多」常见在调度类、构造类题目中

💡 三、常见贪心策略与经典题型

题型贪心策略示例题目(Leetcode)
区间调度按结束时间排序,选不冲突的最多435. 无重叠区间
跳跃游戏每一步尽量跳得远55. Jump Game / 45. Jump Game II
字符串构造局部最小字母优先、单调栈维护字典序316. 去除重复字母
零钱找零从大面额向小面额选(注意反例)860. 柠檬水找零
频率冲突减少冲突频次1647. 删除字符使频次唯一
多任务调度按结束时间/负载等排序253. 会议室 II
区间合并按起点排序合并重叠区间56. Merge Intervals
装箱问题优先选单位价值高的类似背包问题的变种

📚 四、推荐练习题目

Leetcode 题号标题贪心策略
455分发饼干小饼干喂小胃口
435无重叠区间结束时间排序
55 / 45Jump Game I / II尽量跳远
134加油站净油量分析
406根据身高重建队列高的先排,按插入序处理
763划分字母区间尽量延长当前分段直到包含所有字符
621任务调度器贪心找频次最大任务
1647删除字符使频次唯一贪心频率递减+哈希

❗ 五、常见误区

误区说明
❌ 所有最小/最大问题都能贪心若问题有依赖关系,需用动态规划
❌ 贪心算法没有模板只能硬猜虽无统一模板,但常见场景有套路
❌ 贪心和动态规划完全互斥有些题目局部用贪心能优化 DP 的子问题

✅ 总结口诀

能排序就排序,
能局部选就选,
能不回头就不回,
目标问最多/最少/是否能做到,很可能是贪心。

1647. 字符频次唯一的最小删除次数

给定一个字符串 s,你可以通过从字符串中删除一些字符使得剩下的字符串满足如下条件: 所有字符出现的次数都不相同 返回你需要删除的最少字符数,使得最终字符串满足要求。 输入: s = “aaabbbcc” 输出: 2 解释: 你可以删除两个 ‘b’ 或者一个 ‘b’ 和一个 ‘c’,使得每个字符出现次数唯一。

 1from collections import Counter
 2def minDeletions(self, s):
 3    c = Counter(s)
 4    used = {}
 5    count = 0
 6    for char, freq in c.items():
 7
 8        while freq > 0 and freq in used:
 9            freq -= 1
10            count += 1
11        
12        used[freq] = True
13    return count