435.无重叠区间
就是取 区间1 和 区间2 右边界的最小值,因为这个最小值之前的部分一定是 区间1 和区间2 的重合部分,如果这个最小值也触达到区间3,那么说明 区间 1,2,3都是重合的。
class Solution:#基于左边界
def eraseOverlapIntervals(self, intervals: List[List[int]]) -> int:
if not intervals:
return 0
intervals.sort(key=lambda x:x[0])#按照左边界升序排序
count=0
for i in range(1,len(intervals)):
if intervals[i][0]<intervals[i-1][1]:#存在重叠区间
intervals[i][1]=min(intervals[i-1][1],intervals[i][1])#更新重叠区间
count+=1
return count
class Solution:#基于左边界法2
def eraseOverlapIntervals(self, intervals: List[List[int]]) -> int:
if not intervals:
return 0
intervals.sort(key=lambda x:x[0])
result=1#不重叠区间的数量,初始化为1,因为至少有一个不重叠的区间
for i in range(1,len(intervals)):
if intervals[i][0]>=intervals[i-1][1]:
result+=1
else:
intervals[i][1]=min(intervals[i-1][1],intervals[i][1])# 更新重叠区间的右边界
return len(intervals)- result
用总区间数减去弓箭数量 就是要移除的区间数量了。
763划分字母区间
- 统计每一个字符最后出现的位置
- 从头遍历字符,并更新字符的最远出现下标,如果找到字符最远出现位置下标和当前下标相等了,则找到了分割点
class Solution:
def partitionLabels(self, s: str) -> List[int]:
last_occurrence={}#统计每个字符最后出现的位置
for i,ch in enumerate(s):
last_occurrence[ch]=i
result=[]
start=0
end=0
for i,ch in enumerate(s):
end=max(end,last_occurrence[ch])
if i==end: # 如果当前位置是最远位置,表示可以分割出一个区间
result.append(end-start+1)
start=i+1
return result
56. 合并区间
class Solution:
def merge(self, intervals: List[List[int]]) -> List[List[int]]:
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