tasks for today: (贪心算法----重叠区间问题)
1. 452.用最少数量的箭引爆气球
2. 435.无重叠区间
3. 763.划分字母区间
------------------------------------------------------------------------------------------
1. 452.用最少数量的箭引爆气球
为了让气球尽可能的重叠,需要对数组进行排序。
如果气球重叠了,重叠气球中右边边界的最小值 之前的区间一定需要一个弓箭。
the greedy mindset is reflected on: calculating the maximum number of overlap is counted as one arrow.
Another key point is: at least one arrow is used because the points list is not void.
class Solution:
def findMinArrowShots(self, points: List[List[int]]) -> int:
points.sort(key=lambda x: (x[0], x[1]))
sl, sr = points[0][0], points[0][1]
# at least one arrow
count = 1
for i in points:
if i[0] > sr:
count += 1
sl = i[0]
sr = i[1]
else:
sl = max(sl, i[0])
sr = min(sr, i[1])
return count
2. 435.无重叠区间
This practice is similar to the practice 452, the count of arrows would be the max overlap counts, which means the len(interval) - count would be the min number of removal of interval
One key point is, the [1,2] [2,3] will be treated as two contingent interval, not overlapped.
class Solution:
def eraseOverlapIntervals(self, intervals: List[List[int]]) -> int:
count = 1
intervals.sort(key=lambda x: (x[0], x[1]))
sl, sr = intervals[0][0], intervals[0][1]
for i in intervals:
if i[0] >= sr:
count += 1
sl, sr = i[0], i[1]
else:
sl = max(i[0], sl)
sr = min(i[1], sr)
return len(intervals) - count
3. 763.划分字母区间
可以分为如下两步:
- 统计每一个字符最后出现的位置
- 从头遍历字符,并更新字符的最远出现下标,如果找到字符最远出现位置下标和当前下标相等了,则找到了分割点
class Solution:
def partitionLabels(self, s: str) -> List[int]:
lastshowup = {}
for i, ch in enumerate(s):
lastshowup[ch] = i
# print(lastshowup)
result = []
start, end = 0, 0
for i, ch in enumerate(s):
# if no this, there might be some shorter match within the segment
end = max(end, lastshowup[ch])
if i == end:
# print(i)
result.append(end - start + 1)
start = i + 1
return result