LeetCode 435. 无重叠区间
力扣题目链接
本题与区间调度问题类似,找到最多的互不相交区间之后,剩余的区间就是要移除区间的最小数量。
class Solution:
def eraseOverlapIntervals(self, intervals: List[List[int]]) -> int:
if not intervals: return 0
# 按 end 升序排序
intervals.sort(key=lambda x: x[1])
# 至少有一个区间不相交
count = 1
# 排序后第一个区间是x
x_end = intervals[0][1]
for i in range(1, len(intervals)):
if intervals[i][0] >= x_end:
# 找到下一个区间了
count += 1
x_end = intervals[i][1]
return len(intervals) - count
区间调度问题(Interval Scheduling)
问题描述:给你很多形如[start, end]
的闭区间,请你设计一个算法,算出这些区间中最多有几个互不相交的区间。
举个例子,intvs = [[1,3], [2,4], [3,6]]
,这些区间最多有 2 个区间互不相交,即 [[1,3], [3,6]]
,你的算法应该返回 2。注意边界相同并不算相交。
正确的思路其实很简单,可以分为以下三步:
- 从区间集合
intvs
中选择一个区间x
,这个x
是在当前所有区间中结束最早的(end
最小)。 - 把所有与
x
区间相交的区间从区间集合intvs
中删除。 - 重复步骤 1 和 2,直到
intvs
为空为止。之前选出的那些x
就是最大不相交子集。
LeetCode 763.划分字母区间
我的思路:先统计出每个字母的索引区间,然后就是区间调度问题,寻找一些互不相交的区间
class Solution:
def partitionLabels(self, s: str) -> List[int]:
record = dict()
for i in range(len(s)):
if s[i] not in record.keys():
record[s[i]] = [i, i]
else:
record[s[i]][1] = i
result = [0]
intervals = [x for x in record.values()]
x_end = intervals[0][1]
curSum = 0
for i in range(1, len(intervals)):
if intervals[i][0] >= x_end:
result.append(x_end - curSum + 1)
curSum += result[-1]
x_end = intervals[i][1]
else:
x_end = max(x_end, intervals[i][1])
if sum(result) < len(s):
result.append(len(s) - sum(result))
return result[1:]
LeetCode 56. 合并区间
区间合并问题,与上一题类似
class Solution:
def merge(self, intervals: List[List[int]]) -> List[List[int]]:
intervals.sort(key=lambda x: (x[0], x[1]))
result = []
x_start = intervals[0][0]
x_end = intervals[0][1]
for i in range(1, len(intervals)):
if intervals[i][0] <= x_end:
x_end = max(x_end, intervals[i][1])
else:
result.append([x_start, x_end])
x_start = intervals[i][0]
x_end = intervals[i][1]
result.append([x_start, x_end])
return result
# 解法二:
class Solution:
def merge(self, intervals):
result = []
if len(intervals) == 0:
return result # 区间集合为空直接返回
intervals.sort(key=lambda x: x[0]) # 按照区间的左边界进行排序
result.append(intervals[0]) # 第一个区间可以直接放入结果集中
for i in range(1, len(intervals)):
if result[-1][1] >= intervals[i][0]: # 发现重叠区间
# 合并区间,只需要更新结果集最后一个区间的右边界,因为根据排序,左边界已经是最小的
result[-1][1] = max(result[-1][1], intervals[i][1])
else:
result.append(intervals[i]) # 区间不重叠
return result
今日毕!