文章目录
- [LeetCode:452. 用最少数量的箭引爆气球](#LeetCode:452. 用最少数量的箭引爆气球)
- [LeetCode:435. 无重叠区间](#LeetCode:435. 无重叠区间)
- [LeetCode:763. 划分字母区间](#LeetCode:763. 划分字母区间)
LeetCode:452. 用最少数量的箭引爆气球
https://leetcode.cn/problems/minimum-number-of-arrows-to-burst-balloons/description/
思路
- 将所有区间按照
xend从小到大排列。 - 第一支箭射在第一个区间的右端点。
- 遍历后续区间:
(1)如果当前区间的左端点xstart大于上一支箭的位置,说明这支箭无法射中当前气球,必须发射一支新箭,并将新箭的位置设为当前区间的右端点。
(2)否则,当前区间可以被上一支箭覆盖,无需新箭。
解答
python
class Solution:
def findMinArrowShots(self, points: List[List[int]]) -> int:
points.sort(key=lambda x: x[1]) # 按区间右端点升序排序
arrows = 1
current_end = points[0][1] # 第一支箭的位置
for xstart, xend in points[1:]:
if xstart > current_end: # 如果当前气球左端点 > 上一支箭的位置,需要新箭
arrows += 1
current_end = xend
return arrows
LeetCode:435. 无重叠区间
https://leetcode.cn/problems/non-overlapping-intervals/
思路
贪心时选择最早结束的区间,可以最大化剩余空间,使得后续有更多区间可能被容纳。
解答
python
class Solution:
def eraseOverlapIntervals(self, intervals: List[List[int]]) -> int:
intervals.sort(key=lambda x: x[1]) # 按区间右端点升序排序
last_end = intervals[0][1]
remain = 1 # 至少保留一个
for start, end in intervals[1:]:
if start >= last_end: # 不重叠,保留
remain += 1
last_end = end
return len(intervals) - remain
LeetCode:763. 划分字母区间
https://leetcode.cn/problems/partition-labels/
思路
- 第一次遍历:记录每个字符在字符串中最后出现的索引。
- 第二次遍历:
(1)初始化start = 0,end = 0。
(2)遍历每个字符s[i],更新end = max(end, last_index[s[i]]),表示当前片段必须延伸到当前字符的最后出现位置。
(3)当i == end时,说明从start到end的片段已经包含了所有出现的字符,且不会与后面的片段冲突,因此可以切分。记录长度end - start + 1,然后将start更新为i + 1。
解答
python
class Solution:
def partitionLabels(self, s: str) -> List[int]:
# 统计每一个字符最后出现的位置
last_index = {}
n = len(s)
for i in range(n):
last_index[s[i]] = i
results = []
start = 0
end = 0
for i in range(n):
end = max(end, last_index[s[i]])
if i == end:
results.append(end - start + 1)
start = i + 1
return results