494 字
2 分钟
代码随想录算法训练营第二十六天 | 贪心算法 Part04

区间贪心算法#

本节聚焦于区间贪心类问题:以区间的右端点排序是解决“重叠最小化”或“最少操作”的核心策略。


452. 用最少数量的箭引爆气球#

LeetCode 452. Minimum Number of Arrows to Burst Balloons

  • 按右端点排序
  • 每次选一支箭射当前区间的右端点,跳过所有与之重叠的气球;
  • 不重叠则再射一箭。
class Solution:
def findMinArrowShots(self, points: List[List[int]]) -> int:
if not points:
return 0
# 按气球的右边界升序排列
points.sort(key=lambda x: x[1])
count = 1 # 至少一支箭
x_end = points[0][1] # 当前箭射的位置
for point in points:
start = point[0]
if start > x_end:
# 当前气球与上一支箭不重叠,需要额外一支箭
count += 1
x_end = point[1]
return count

435. 无重叠区间#

LeetCode 435. Non-overlapping Intervals

  • 和上一题类似,按右端点升序;
  • 每次选能不重叠的最多区间数;
  • 用总数减去最多可选数,就是最少删除数。
class Solution:
def eraseOverlapIntervals(self, intervals: List[List[int]]) -> int:
n = len(intervals)
if not intervals:
return 0
# 按右端点升序排序
intervals.sort(key=lambda x: x[1])
count = 1 # 至少保留一个不重叠区间
x_end = intervals[0][1]
for interval in intervals:
start = interval[0]
if start >= x_end:
# 当前区间不重叠,可以保留
count += 1
x_end = interval[1]
# 要删除的区间数 = 总数 - 可保留数
return n - count

763. 划分字母区间#

LeetCode 763. Partition Labels

  • 记录每个字符最后出现的位置;
  • 从左到右遍历更新当前分区的最大边界;
  • 当遍历到最大边界位置时,可以分区。
class Solution:
def partitionLabels(self, s: str) -> List[int]:
# 记录每个字母最后一次出现的位置
last_pos = {ch: i for i, ch in enumerate(s)}
res = []
start = end = 0
for i, ch in enumerate(s):
# 当前分区最远可以延伸到 ch 的最后位置
end = max(end, last_pos[ch])
if i == end:
# 当前 i 达到分区边界,可以切分
res.append(end - start + 1)
start = i + 1
return res
代码随想录算法训练营第二十六天 | 贪心算法 Part04
https://fuwari.vercel.app/posts/code_musings_day_twenty-six/
作者
Jarrett
发布于
2025-07-10
许可协议
CC BY-NC-SA 4.0