435.无重叠区间
题目链接:435. 无重叠区间 - 力扣(LeetCode)
文章讲解:代码随想录 (programmercarl.com)
视频讲解:贪心算法,依然是判断重叠区间 | LeetCode:435.无重叠区间哔哩哔哩bilibili
思路:
class Solution:
def eraseOverlapIntervals(self, intervals: List[List[int]]) -> int:
# 如果区间集合为空,返回0
if not intervals:
return 0
intervals.sort(key=lambda x: x[0])
# 初始化移除区间的数量为0
remove_count = 0
# 初始化上一个不重叠区间的结束位置为第一个区间的结束位置
end = intervals[0][1]
for i in intervals[1:]:
# 存在重叠区间
if i[0] < end:
# 更新重叠区间的右边界:选一个结束位置小的区间,减少重叠
end = min(i[1],end)
remove_count += 1
else:
end = i[1]
return remove_count
感想:与上一题气球一样,删除重叠区间
763.划分字母区间
题目链接:763. 划分字母区间 - 力扣(LeetCode)
文章讲解:代码随想录 (programmercarl.com)
视频讲解:贪心算法,寻找最远的出现位置! LeetCode:763.划分字母区间哔哩哔哩bilibili
思路:
class Solution:
def partitionLabels(self, s: str) -> List[int]:
last_index = {} # 记录每个字母最后出现的位置
for i, char in enumerate(s):
last_index[char] = i
result = [] # 存储结果的列表
start = end = 0 # 当前片段的起始位置和结束位置
for i, char in enumerate(s):
end = max(end, last_index[char]) # 更新当前片段的结束位置
if i == end: # 当前位置等于结束位置,表示当前片段结束
result.append(end - start + 1) # 将当前片段的长度添加到结果列表中
start = end + 1 # 更新下一个片段的起始位置
return result
56.合并区间
题目链接:56. 合并区间 - 力扣(LeetCode)
文章讲解:代码随想录 (programmercarl.com)
视频讲解:贪心算法,合并区间有细节!LeetCode:56.合并区间哔哩哔哩bilibili
思路:
class Solution:
def merge(self, intervals: List[List[int]]) -> List[List[int]]:
# 按照区间的起始位置进行排序
intervals.sort(key=lambda x:x[0])
# print(intervals)
result = [] # 存储合并后的区间
# 初始化起始位置和结束位置为第一个区间的起始位置和结束位置
start = intervals[0][0]
end = intervals[0][1]
# 遍历排序后的区间列表
for i in intervals[1:]:
# 如果当前区间的起始位置小于等于当前合并后的最后一个区间的结束位置,
# 则更新当前合并后的最后一个区间的结束位置为这两个区间的结束位置的最大值
if i[0] <= end:
end = max(end,i[1])
else:
# 否则,当前区间和当前合并后的最后一个区间无重叠,
# 将当前合并后的区间加入到结果列表中,并更新起始位置和结束位置为当前区间的起始位置和结束位置
result.append([start,end])
start = i[0]
end = i[1]
# 将最后一个合并后的区间加入到结果列表中
result.append([start, end])
return result
这种思路比较好理解,我们可以根据上面的代码进行改进
直接将区间添加到结果集,与下一个区间比较,更新右边界
class Solution:
def merge2(self, intervals: List[List[int]]) -> List[List[int]]:
# 按照区间的起始位置进行排序
intervals.sort(key=lambda x: x[0])
merged = [] # 存储合并后的区间
for interval in intervals:
# 如果merged为空,或当前区间的起始位置大于当前合并后的最后一个区间的结束位置,则直接将当前区间加入到merged中
if not merged or interval[0] > merged[-1][1]:
merged.append(interval)
else:
# 否则,更新当前合并后的最后一个区间的结束位置为这两个区间的结束位置的最大值
merged[-1][1] = max(merged[-1][1], interval[1])
return merged
题目中说明了集合长度至少为1,说明没有空集合,但是这个为了代码的完整性,改进代码还是补充了判空