day30-greedy-part04-8.1

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
  • 22
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值