如何掌握贪心算法与区间问题面试题
贪心算法是各级别技术面试的常客。从初级工程师的编程筛选到资深工程师的深度考核,面试官都会用贪心问题来检验你能否识别局部最优选择并将其推广到全局最优解。难点往往不在代码本身,而在于识别贪心策略的适用性并证明其正确性。借助 AI 面试助手 强化你的模式识别能力,你可以在任何编程面试中自信地捕捉到贪心信号。
为什么贪心算法在面试中如此常见
贪心算法看似简单,实则暗藏玄机。代码通常很简短,但背后的正确性推理才是区分强弱候选人的关键。面试官青睐贪心问题,因为它同时考察三个维度:模式识别(贪心是否适用?)、证明直觉(为什么局部选择能导向全局最优?)以及边界情况意识(多个元素相等或输入为空时怎么办?)。
与动态规划探索所有子问题不同,贪心算法在每一步做出一个选择后就不再回头。这使得贪心解法效率极高——通常由于排序而达到 O(n log n)——但也很脆弱。一个适用于某变体的贪心策略可能在稍作修改后完全失效。这种简洁与正确性之间的张力,正是这类题目成为面试利器的原因。
贪心何时有效?
在深入具体模式之前,你需要一个判断贪心是否适用的思维框架。以下两个性质必须同时满足:
贪心选择性质
通过在每一步做出局部最优选择,可以得到全局最优解。你无需重新考虑已做出的决定。
最优子结构
做出贪心选择后,剩余的子问题与原问题具有相同的结构。子问题的最优解加上贪心选择,就构成了原问题的最优解。
如果两个性质都满足,贪心有效。如果任一性质缺失,你可能需要动态规划或其他技术。面试中,快速验证的方法是尝试构造一个反例。如果几次尝试后找不到反例,贪心大概率是安全的。
六大核心贪心模式
模式一:区间调度与活动选择
这是最经典的贪心模式。给定一组区间(活动、会议、任务),选择最大数量的互不重叠的区间。
核心洞察:按结束时间排序,然后贪心地选择不与前一个已选区间重叠的最早结束的区间。
为什么按结束时间排序而不是开始时间?因为选择最早结束的区间为后续区间留出了最大空间。按开始时间排序可能导致你选中一个很长的区间,从而阻塞许多较短的区间。
时间复杂度:排序 O(n log n),贪心扫描 O(n)。
常见变体:
- 一个人最多能参加多少个不重叠的会议
- 所需的最少会议室数量(此变体使用不同技巧——见模式二)
- 射爆重叠气球所需的最少箭数
模式二:合并区间
给定一组区间,合并所有重叠区间并返回不重叠的区间列表。
解题方法:按开始时间排序。用第一个区间初始化结果。对于后续每个区间,检查它是否与结果中最后一个区间重叠(即其开始时间小于等于前一个的结束时间)。如果重叠,将前一个的结束时间扩展为两者的最大值。如果不重叠,将新区间加入结果。
为什么有效:按开始时间排序保证了如果区间 B 与区间 A 重叠,B 会紧跟在 A 之后出现(或在同一合并组中)。排序后出现的任何区间如果不与 B 重叠,也不可能与 A 重叠。
时间复杂度:排序 O(n log n),合并扫描 O(n)。
常见变体:
- 将新区间插入到已排序的不重叠区间列表中
- 求最少会议室数(使用最小堆跟踪结束时间,或扫描线 +1/-1 事件法)
- 判断一个人是否能参加所有会议(排序后检查是否有重叠即可)
模式三:跳跃游戏与可达性
给定一个数组,每个元素代表从该位置可以跳跃的最大长度,判断是否能到达最后一个下标(或求最少跳跃次数)。
可达性的贪心洞察:维护变量 maxReach 跟踪当前能到达的最远下标。遍历数组:在每个下标 i 处,更新 maxReach = max(maxReach, i + nums[i])。如果在某个点 i > maxReach,则无法继续。如果 maxReach 达到或超过最后一个下标,返回 true。