贪心算法故事:拖延症小明的作业危机

贪心算法就像一位"永远只选眼前最优解"的冒险家,每次决策都选择当下最有利的选项,逐步逼近全局最优解。下面我用一个​​拖延症学生赶作业​​的故事,带你彻底理解其精髓!


📖 ​​故事:拖延症小明的作业危机​

小明周日晚上才发现有5项作业没做,每项耗时不同:
数学(60分钟), 语文(30分钟), 英语(15分钟), 物理(45分钟), 化学(20分钟)

他要在2小时内(120分钟)完成尽可能多的作业。

⚡ ​​贪心策略​​:

​每次都选当前耗时最短的作业​​(快速清掉小任务,腾出更多时间)

  1. 选最短:​英语(15min)​ → 剩余时间105min
  2. 选次短:​化学(20min)​ → 剩余85min
  3. 选第三短:​语文(30min)​ → 剩余55min
  4. 选第四短:​物理(45min)​ → 剩余10min
  5. 数学需60min(但剩余时间不足)→ 放弃

​结果​​:完成4项作业(总耗时110min),比按顺序做(只能做3项)更优!


⚙️ ​​贪心算法核心原理​

​1. 两大黄金定律​

​特性​ ​含义​ ​小明例子​
​贪心选择性质​ 局部最优选择能导向全局最优解 每次选最短作业 → 完成总数最多
​最优子结构​ 大问题的最优解由子问题最优解组成 完成4项 = 前4项最优解的组合

​2. 与动态规划的区别​

💡 贪心永不回溯(高效但可能非全局最优),动态规划会回看历史(准确但更慢)


💻 ​​Java代码实战:作业调度贪心算法​

typescript 复制代码
java
Copy
import java.util.*;  

public class GreedyHomework {  
    public static void main(String[] args) {  
        // 作业列表:<科目, 耗时>  
        Map<String, Integer> homework = new HashMap<>();  
        homework.put("数学", 60);  
        homework.put("语文", 30);  
        homework.put("英语", 15);  
        homework.put("物理", 45);  
        homework.put("化学", 20);  

        // 贪心核心:按耗时升序排序  
        List<Map.Entry<String, Integer>> sortedList = new ArrayList<>(homework.entrySet());  
        sortedList.sort(Map.Entry.comparingByValue()); // 按耗时排序[11](@ref)  

        // 执行作业  
        int totalTime = 120;  
        List<String> completed = new ArrayList<>();  
        for (Map.Entry<String, Integer> task : sortedList) {  
            if (totalTime >= task.getValue()) {  
                completed.add(task.getKey());  
                totalTime -= task.getValue();  
            } else {  
                break; // 时间不足时停止  
            }  
        }  

        System.out.println("完成作业:" + completed);  
        System.out.println("剩余时间:" + totalTime + "分钟");  
    }  
}  

​运行结果​​:

css 复制代码
Copy
完成作业:[英语, 化学, 语文, 物理]  
剩余时间:10分钟  

⚠️ ​​贪心算法的陷阱:何时会失效?​

​1. 非标准货币找零问题​

若硬币面额为:[1, 5, 11],要凑出​​15元​​:

  • 贪心:11+1+1+1+1 → ​​5枚硬币​

  • 实际最优:5+5+5 → ​​3枚硬币​​(贪心失效!)

​2. 适用条件总结​

​场景​ ​是否适用贪心​ ​原因​
标准找零(1/5/10) ✅ 是 大面额总能组成最优解
非标准找零 ❌ 否 局部最优≠全局最优
活动安排问题 ✅ 是 早结束的活动优先保证更多安排8
背包问题(物品可分割) ✅ 是 优先选价值密度最高的物品

🚨 ​​黄金法则​ ​:使用前必须证明问题满足​​贪心选择性质​​!


🌐 ​​经典应用场景与Java实现​

​1. 活动安排问题(最多不相交区间)​

ini 复制代码
java
Copy
// 按结束时间排序 → 每次选最早结束的活动[8,10](@ref)  
Arrays.sort(activities, (a, b) -> a.end - b.end);  
int count = 1, lastEnd = activities[0].end;  
for (int i = 1; i < activities.length; i++) {  
    if (activities[i].start >= lastEnd) {  
        count++;  
        lastEnd = activities[i].end;  
    }  
}  

​2. 股票买卖(多次交易)​

ini 复制代码
java
Copy
// 只要今天比昨天涨就卖出[5](@ref)  
int profit = 0;  
for (int i = 1; i < prices.length; i++) {  
    if (prices[i] > prices[i - 1]) {  
        profit += prices[i] - prices[i - 1];  
    }  
}  

​3. 霍夫曼编码(数据压缩)​

优先合并频率最小的字符 → 构建最优前缀树


💎 ​​总结:一图掌握贪心算法​

​面试口诀​​:

眼前利益最大化,全局最优需验证。

活动排序找零钱,子结构是通行证!

试着运行文中的作业调度代码,调整时间限制和作业时长,观察贪心策略的变化。记住:​​贪心算法是面试高频考点,重点在于识别问题是否具备贪心选择性质!​

相关推荐
_荒9 分钟前
uniapp AI流式问答对话,问答内容支持图片和视频,支持app和H5
android·前端·vue.js
冰糖葫芦三剑客10 分钟前
Android录屏截屏事件监听
android
东风西巷29 分钟前
LSPatch:免Root Xposed框架,解锁无限可能
android·生活·软件需求
用户2018792831672 小时前
图书馆书架管理员的魔法:TreeMap 的奇幻之旅
android
androidwork2 小时前
Kotlin实现文件上传进度监听:RequestBody封装详解
android·开发语言·kotlin
雨白2 小时前
从拍照到相册,安全高效地处理图片
android
androidwork2 小时前
解析401 Token过期自动刷新机制:Kotlin全栈实现指南
android·kotlin
-SOLO-2 小时前
使用Trace分析Android方法用时
android
yzpyzp2 小时前
Android 的AppBarLayout 与LinearLayput的区别
android
爱装代码的小瓶子2 小时前
字符操作函数续上
android·c语言·开发语言·数据结构·算法