算法总结
· 阅读需 4 分钟
记录做力扣面试经典150过程中遇到的算法🤔
贪心算法
🎯 识别贪心算法适用场景的技巧
1. 问题特征识别
以下特征通常表明可以使用贪心算法:
✅ 最优子结构:问题的最优解包含子问题的最优解 ✅ 贪心选择性质:局部最优选择能导致全局最优 ✅ 无后效性:当前选择不会影响之前的状态 ✅ 求极值问题:最大值、最小值、最优解等
2. 常见问题类型
以下类型问题经常使用贪心策略:
🔢 选择问题:活动选择、区间调度 💰 优化问题:背包问题变种、股票买卖 🗺️ 图论问题:最小生成树、最短路径 📊 数据处理:哈夫曼编码、任务调度 🎯 游戏策略:跳跃游戏、分配问题
🎯 如何快速判断的技巧
技巧1:问自己几个关键问题
- 是否可以通过一系列局部选择得到全局最优解?
- 当前的最优选择是否会影响后续的决策空间?
- 如果每步都选当前最好的,最终结果是否最优?
- 是否存在反例能证明贪心不成立?
技巧2:看问题的关键词
出现这些关键词时考虑贪心:
- "最大"、"最小"、"最优"
- "尽可能"、"最多"、"最少"
- "安排"、"调度"、"分配"
- "使得总...最大/最小"
🎯 如何设计贪心策略
1. 确定贪心选择标准
关键步骤:
- 明确每一步要做出什么选择
- 确定衡量"好"选择的标准
- 证明这个选择标准的正确性
2. 举例分析
股票买卖问题分析:
- 问题:如何获得最大利润?
- 贪心选择:只要明天比今天贵,今天就买入明天卖出
- 选择标准:价格正增长就交易
- 正确性:所有正收益都 captured,负收益都避免
跳跃游戏问题分析:
- 问题:能否到达终点?
- 贪心选择:每到一个位置,尽可能扩展可达范围
- 选择标准:选择能让maxReach最大的策略
- 正确性:最大可达范围决定了能否到达终点
🎯 实战判断流程
三步判断法:
Step 1: 问题分析
- 这是一个优化问题吗?(求最大/最小值)
- 是否可以分解为一系列选择?
Step 2: 贪心假设
- 能否通过局部最优选择得到全局最优?
- 假设贪心策略,能否构造反例?
Step 3: 策略设计
- 明确每步的贪心选择是什么
- 确定如何衡量选择的好坏
- 验证算法正确性
🎯 常见贪心策略模板
1. 选择类问题
// 模板:按某种标准排序后贪心选择
sort(elements, compare_function); // 首先按某种标准排序
for (each element) { // 遍历每个元素
if (can_select(element)) { // 如果可以选择当前元素
select(element); // 就选择它
}
}
2. 扩展类问题
// 模板:逐步扩展最优解
for (each step) { // 遍历每个决策步骤
best_choice = find_best_local_choice(); // 在当前步骤中找到局部最优选择
if (is_better(best_choice)) { // 如果这个选择比当前解更好
update_solution(best_choice); // 就用这个选择更新当前最优解
}
}
3. 累积类问题
// 模板:累积局部最优解
total_result = 0; // 初始化总结果为0
for (each sub_problem) { // 遍历每个子问题
local_optimal = solve_locally(); // 求解当前子问题的局部最优解
total_result += local_optimal; // 将局部最优解累加到总结果中
}
💡 实用建议
- 多练习经典贪心问题:活动选择、背包问题、霍夫曼编码等
- 学会构造反例:如果想不出反例证明贪心成立
- 关注边界条件:贪心算法常在边界处出错
- 证明贪心选择性质:虽然面试不要求严格证明,但思路要清晰
记住:贪心算法的关键在于识别问题的贪心性质和设计正确的贪心策略,这需要大量的练习和经验积累。
加载评论中...