贪心算法(Greedy Algorithm)是一种非常有趣的算法思想,它像极了我们在生活中做决策的方式——每一步都选择当前看起来最好的选项。你可能在不经意间用过它,比如在超市结账时选择最短的队伍排队。本文将通过生动的例子和Java代码实现,带你轻松掌握贪心算法的精髓!
贪心算法的核心思想非常简单:在每一个决策点,都选择当前状态下最优的解决方案,最终通过这些局部最优解组合得到全局最优解。
假设你有面额为1元、5元、10元的硬币,需要支付36元且硬币数量最少。贪心算法的思路是:
贪心算法虽然简单,但不是所有问题都适用。需要满足两个关键条件:
⚠️ 注意:某些情况下贪心算法会失效(例如硬币面额为25、20、10分时,用贪心法找40分会导致错误)。此时需要动态规划等其他方法。
假设有多个活动,每个活动有开始和结束时间。如何选择最多数量的互不冲突的活动?
每次选择结束时间最早的活动,这样能为后续活动留出更多时间。
import java.util.*;
class Activity {
int start;
int end;
public Activity(int start, int end) {
this.start = start;
this.end = end;
}
}
public class GreedyExample {
public static void main(String[] args) {
List<Activity> activities = Arrays.asList(
new Activity(1, 4), new Activity(3, 5),
new Activity(0, 6), new Activity(5, 7),
new Activity(3, 9), new Activity(5, 9)
);
// 按结束时间排序
activities.sort((a1, a2) -> a1.end - a2.end);
List<Activity> selected = new ArrayList<>();
int lastEnd = 0;
for (Activity act : activities) {
if (act.start >= lastEnd) {
selected.add(act);
lastEnd = act.end;
}
}
System.out.println("最多可安排活动数: " + selected.size());
selected.forEach(a -> System.out.println("活动时间: " + a.start + "-" + a.end));
}
}
最多可安排活动数: 3
活动时间: 1-4
活动时间: 5-7
活动时间: 5-9
遇到以下特征时,可以考虑贪心算法:
✅ 优点
❌ 缺点
贪心算法就像一位精明的决策者,永远选择当下最好的选项。记住它的两个关键:局部最优选择和无后效性。当遇到符合条件的问题时,不妨试试这个简单高效的算法!
下次遇到需要做序列决策的问题时,不妨先问问自己:“如果每次都选当前最好的,最终能得到全局最优吗?” 如果答案是肯定的,那么贪心算法就是你的最佳选择!
扩展思考:尝试用贪心算法解决「部分背包问题」(物品可拆分),并与0-1背包问题对比,理解贪心法的适用边界。