Leetcode
本题可以计算重叠的区间数量,也可以计算不重叠的区间数量。我采用的是计算重叠的区间数量。
具体的细节和452.用最少数量的箭引爆气球很相似。
class Solution:
def eraseOverlapIntervals(self, intervals: List[List[int]]) -> int:
intervals.sort(key = lambda x : x[0])
res = 0
for i in range(1, len(intervals)):
if intervals[i][0] >= intervals[i-1][1]:
continue
else:
res += 1
intervals[i][1] = min(intervals[i][1], intervals[i-1][1])
return res
基于左边界 把452.用最少数量的箭引爆气球代码稍做修改
class Solution:
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
O(nlog n)
,有一个排序O(1)
Leetcode
在遍历的过程中相当于是要找每一个字母的边界,如果找到之前遍历过的所有字母的最远边界,说明这个边界就是分割点了。此时前面出现过所有字母,最远也就到这个边界了。
可以分为如下两步:
class Solution:
def partitionLabels(self, s: str) -> List[int]:
distanceDict = {}
for i in range(len(s)):
distanceDict[s[i]] = i
length = 0
maxIndex = 0
res = []
for i in range(len(s)):
length += 1
maxIndex = max(maxIndex, distanceDict[s[i]])
if i == maxIndex:
res.append(length)
length = 0
return res
O(n)
O(1)
,使用的hash数组是固定大小Leetcode
思路和前面的题类似,使用相同的方法判断是否存在重叠的区间。
但是需要注意的是,因为我们不仅需要判断重叠区间,还需要合并重叠的区间,并且最后还要将它们返回,所以我们新建一个二维数组来帮助我们完成这项任务。
在最开始的时候,res
直接放入intervals[0]
来方便后续的比对。
这样的操作避免了以下难题:
res
res
上进行区间的合并,不需要将区间从res
拿出来再放入。class Solution:
def merge(self, intervals: List[List[int]]) -> List[List[int]]:
if len(intervals) <= 1:
return intervals
intervals.sort(key = lambda x:x[0])
res = [intervals[0]]
for i in range(1, len(intervals)):
if intervals[i][0] <= res[-1][1]:
res[-1] = [res[-1][0], max(intervals[i][1], res[-1][1])]
else:
res.append(intervals[i])
return res
O(nlogn)
O(logn)