给定一个区间的集合 intervals
,其中 intervals[i] = [starti, endi]
。返回 需要移除区间的最小数量,使剩余区间互不重叠 。
思路:跟打爆气球类似,将区间看作是气球的位置就行。不同的地方在于:需要先给区间排序,并且区间的边界重合不算是重叠。
class Solution:
def eraseOverlapIntervals(self, intervals: List[List[int]]) -> int:
if not intervals:
return 0
intervals.sort(key=lambda x:x[0])
arrow = 1
min_right = intervals[0][1]
for i in intervals[1:]:
if i[0] >= min_right:
arrow += 1
min_right = i[1]
else:
min_right = min(i[1], min_right)
return len(intervals) - arrow
给你一个字符串 s
。我们要把这个字符串划分为尽可能多的片段,同一字母最多出现在一个片段中。
注意,划分结果需要满足:将所有划分结果按顺序连接,得到的字符串仍然是 s
。
返回一个表示每个字符串片段的长度的列表。
思路:首先记录每一个字母的最远位置,然后从左往右遍历,遍历的同时维护一个当前最远距离,表示在该位置之前的字母对应的最远距离。如果遍历的位置恰好为最远距离,则说明该位置为在这之前的所有字母的最远距离的最大值,在这里可以划分一个区间,将区间长度放到answer列表中去。
class Solution:
def partitionLabels(self, s: str) -> List[int]:
last_occurrence = {} # 存储每个字符母最后出现的位置
for i, ch in enumerate(s):
last_occurrence[ch] = i
ans = []
start = 0
end = 0
for i, ch in enumerate(s):
end = max(end, last_occurrence[ch]) # 找到当前字母出现的最远位置
if i == end: # 如果当前位置是最远位置,表示可以分割出一个区间
ans.append(end - start + 1)
start = i + 1
return ans
给出一个区间的集合,请合并所有重叠的区间。
示例 1:
- 输入: intervals = [[1,3],[2,6],[8,10],[15,18]]
- 输出: [[1,6],[8,10],[15,18]]
- 解释: 区间 [1,3] 和 [2,6] 重叠, 将它们合并为 [1,6].
示例 2:
- 输入: intervals = [[1,4],[4,5]]
- 输出: [[1,5]]
- 解释: 区间 [1,4] 和 [4,5] 可被视为重叠区间。
- 注意:输入类型已于2019年4月15日更改。 请重置默认代码定义以获取新方法签名。
思路:跟打气球一样,属于区间重叠问题,排序后遍历,维护一个当前重叠区间,如果区间不与当前重叠区间有重叠,则将重叠区间添加到answer列表中,然后更新该区间为新的重叠区间。
Python:
class Solution:
def merge(self, intervals: List[List[int]]) -> List[List[int]]:
ans = []
if not intervals:
return ans
intervals.sort(key= lambda x:x[0])
cache = intervals[0]
for i in intervals:
# 如果该区间与大区间有重叠,则更新大区间
if i[0] <= cache[1]:
cache[1] = max(i[1], cache[1])
else:
ans.append(cache)
cache = i
ans.append(cache) # 遍历到最后时,把最后一个大区间加入到answer列表中
return ans