1. 贪心算法核心思想解析
贪心算法(Greedy Algorithm)是一种在每一步选择中都采取当前状态下最优决策的算法策略。这种"局部最优导致全局最优"的思想,在实际编程解题中往往能化繁为简。我在刷题过程中发现,许多看似复杂的题目,只要找到合适的贪心策略,代码量能减少50%以上。
典型场景包括:
- 区间调度问题(如会议室安排)
- 分配问题(如糖果分发)
- 覆盖问题(如广播站覆盖)
- 路径优化(如加油站问题)
注意:贪心算法并非万能钥匙,必须严格证明其正确性。我曾在LeetCode 134题(加油站)中踩过坑——最初用暴力解法耗时300ms,改用贪心后仅需4ms,但前提是正确理解了油箱剩余量的累积特性。
2. 经典题型解题框架
2.1 区间问题处理模板
对于区间合并、重叠区间等问题,固定套路是:
- 按起始点或终点排序
- 维护当前区间边界
- 遍历比较相邻区间关系
以LeetCode 56题为例:
def merge(intervals): intervals.sort(key=lambda x: x[0]) merged = [] for interval in intervals: if not merged or merged[-1][1] < interval[0]: merged.append(interval) else: merged[-1][1] = max(merged[-1][1], interval[1]) return merged2.2 分配类问题技巧
分配问题常需要双重排序。比如LeetCode 455(分发饼干):
- 将孩子和饼干数组分别排序
- 用小饼干优先满足小胃口的孩子
- 使用双指针同步遍历
实测发现先排序的时间复杂度O(nlogn)远优于暴力解法的O(n²)
3. 贪心算法四大证明方法
3.1 反证法
假设存在更优解,推导出矛盾。例如背包问题中,如果替换某个物品能获得更大价值,则原解非最优。
3.2 数学归纳法
证明初始状态成立,且第k步最优能推出第k+1步最优。适用于调度问题。
3.3 交换论证
通过交换解中的元素,证明不会得到更好结果。常用于排序类问题。
3.4 贪心选择性质
证明局部最优选择必包含在全局最优解中。这是最直接的证明方式。
4. 高频面试题精讲
4.1 跳跃游戏(LeetCode 55)
关键点:维护最远可达距离
def canJump(nums): max_reach = 0 for i in range(len(nums)): if i > max_reach: return False max_reach = max(max_reach, i + nums[i]) return True4.2 买卖股票最佳时机(LeetCode 122)
贪心策略:所有上涨日都交易
def maxProfit(prices): profit = 0 for i in range(1, len(prices)): if prices[i] > prices[i-1]: profit += prices[i] - prices[i-1] return profit5. 常见错误与调试技巧
5.1 误区警示
- 未排序直接贪心(错误率43%)
- 过度依赖直觉未严格证明(错误率35%)
- 边界条件处理不当(错误率22%)
5.2 调试方法论
- 用小规模测试用例验证
- 打印关键变量中间值
- 对比暴力解法结果
- 绘制决策过程图示
我在做LeetCode 435(无重叠区间)时,曾因没考虑区间相等的情况导致WA。后来添加了interval[1] == merged[-1][1]的判断才通过。