🧮 贪心算法 (Greedy Algorithm)
难度 / Difficulty: 中等 (Medium)
分类 / Category: 算法优化 (Optimization Algorithm)
时间复杂度 / Time Complexity: O(n log n) 或 O(n)
空间复杂度 / Space Complexity: O(n) 或 O(1)
📖 算法简介 / Introduction
贪心算法是一种在每一步选择中都采取当前状态下最优(即最有利)选择,从而希望最终得到全局最优解的算法思想。贪心算法不考虑整体最优,而是通过局部最优推导全局最优。
Greedy Algorithm is an algorithmic paradigm that makes locally optimal choices at each step with the hope of eventually finding a global optimum. It never reconsiders choices once made, working in a top-down fashion.
💡 算法原理 / Principle
贪心算法的核心是”每步最优,全局可能最优”:
- 贪心选择 (Greedy Choice):在每一步选择中都采取当前最优的选择
- 最优子结构 (Optimal Substructure):问题的最优解包含其子问题的最优解
- 不可逆性 (Irrevocability):一旦做出选择就无法撤销
核心思想:Make the best decision at each step, hoping that local optimal choices lead to a global optimum. Not all problems have this property — only those with “greedy-choice property” and “optimal substructure.”
🔑 关键概念 / Key Concepts
| 概念 | 说明 |
|---|---|
| 贪心选择性质 (Greedy Choice Property) | 局部最优选择能导出全局最优解 |
| 最优子结构 (Optimal Substructure) | 问题的最优解包含子问题的最优解 |
| 贪心 vs 动态规划 | 贪心只考虑当前,DP考虑所有状态 |
| 证明正确性 | 需要证明每步贪心不会破坏最终解 |
📝 代码实现 / Implementation
# 活动选择问题 - 最多选择不重叠的活动
def activity_selection(activities):
# 按结束时间排序
activities_sorted = sorted(activities, key=lambda x: x[1])
selected = [activities_sorted[0]]
last_end = activities_sorted[0][1]
for start, end in activities_sorted[1:]:
if start >= last_end:
selected.append((start, end))
last_end = end
return selected
# 示例
activities = [(1, 4), (3, 5), (0, 6), (5, 7), (3, 9), (5, 9), (6, 10), (8, 11)]
print(activity_selection(activities))
# 输出: [(1, 4), (5, 7), (8, 11)]
# 霍夫曼编码 - 最小带权路径长度
import heapq
def huffman_coding(frequencies):
heap = [[freq, [char, '']] for char, freq in frequencies]
heapq.heapify(heap)
while len(heap) > 1:
lo = heapq.heappop(heap)
hi = heapq.heappop(heap)
for pair in lo[1:]:
pair[1] = '0' + pair[1]
for pair in hi[1:]:
pair[1] = '1' + pair[1]
heapq.heappush(heap, [lo[0] + hi[0]] + lo[1:] + hi[1:])
return sorted(heap[0][1:], key=lambda p: (len(p[1]), p[0]))
# 示例
freqs = [('a', 45), ('b', 13), ('c', 12), ('d', 16), ('e', 9), ('f', 5)]
print(huffman_coding(freqs))
🎯 应用场景 / Applications
- 活动安排问题 — 选择最多的不重叠活动
- 霍夫曼编码 — 数据压缩中的最优前缀码
- 最小生成树 — Prim 和 Kruskal 算法
- 单源最短路径 — Dijkstra 算法(正权图)
- 零钱找零 — 在特定面额系统下求最优解
- 区间调度 — 会议室安排、任务分配
📊 复杂度分析 / Complexity Analysis
| 类型 | 复杂度 |
|---|---|
| 时间 | O(n log n)(排序)或 O(n)(已知顺序) |
| 空间 | O(n)(存储结果)或 O(1)(原地) |
🏠 实战例题 / Practice Problems
- LeetCode 455 - 分发饼干 - 简单
- LeetCode 435 - 无重叠区间 - 中等
- LeetCode 763 - 划分字母区间 - 中等
- LeetCode 56 - 合并区间 - 中等
| *本文由 AI 自动生成 | Generated by AI* |