你有没有遇到过这种情况:赶时间坐地铁,手里有几张不同面额的零钱,想最快凑出票价?比如要付6元,你有1元、2元和5元的硬币,你会怎么选?大多数人会先拿最大的5元,再补个1元——这其实就是贪心算法的思路。
什么是贪心算法
贪心算法不是数学题里的复杂推导,它更像是一种“眼前最优”的决策方式。每一步都选当前看起来最合适的,不回头也不后悔。虽然不能保证在所有问题上都得到全局最优解,但在很多场景下又快又实用。
一个生活化的例子:找零钱
假设你是小卖部老板,顾客给了你一张20元买了一瓶7元的饮料,你要找回13元。你抽屉里有1元、2元、5元和10元的硬币,怎么给最省事?
大多数人会本能地先拿10元,再拿2元,最后补个1元——一共三枚硬币。这个过程就是贪心策略:每次都选不超过剩余金额的最大面值。
def make_change(coins, amount):
coins.sort(reverse=True) # 从大到小排序
result = []
for coin in coins:
while amount >= coin:
result.append(coin)
amount -= coin
return result
# 使用示例
coins = [1, 2, 5, 10]
change = make_change(coins, 13)
print(change) # 输出: [10, 2, 1]
什么时候能用贪心
不是所有问题都能靠“眼前最优”搞定。比如你手里的硬币是1元、3元和4元,要凑6元。按贪心法会选4+1+1=6,用了三枚;但其实3+3更优,只要两枚。这时候贪心就失灵了。
但它在某些结构明确的问题里特别好使,比如最小生成树(Prim、Kruskal)、最短路径(Dijkstra),甚至文件压缩里的哈夫曼编码,背后都是贪心思想。
写代码时的小技巧
实现贪心算法,关键在于定义清楚“每一步的最优选择”。通常需要对数据预处理,比如排序。像安排会议、装背包、任务调度这类问题,如果能证明局部最优能导向全局最优,就可以大胆用贪心。
比如你一天只有8小时,有五个兼职可选,每个都有开始和结束时间。你想接最多份工作。办法很简单:按结束时间排序,优先选最早结束的,腾出时间给后面的。这就是典型的贪心应用场景。