代码随想录算法训练营第30天|452. 用最少数量的箭引爆气球、435. 无重叠区间、763.划分字母区间

1.452. 用最少数量的箭引爆气球

题目链接:452. 用最少数量的箭引爆气球
文档讲解: 代码随想录

思路:射重叠最多的气球,用的弓箭最少。模拟气球被射爆,没有必要在数组中将元素移走,被射过的气球跳过,记录箭的数量。为了让气球尽可能的重叠,需要对数组进行排序,按照起始位置排序,从前往后遍历,如果气球重叠,重叠气球中右边界最小值需要一个弓箭。

class Solution(object):
    def findMinArrowShots(self, points):
        """
        :type points: List[List[int]]
        :rtype: int
        """
        if not points:
            return 0
        #按照初始位置排序
        points.sort(key = lambda x:x[0])
        res = 1
        for i in range(1,len(points)):
            if points[i][0] > points[i - 1][1]:
                res += 1
            else:
                #更新最小右边界
                points[i][1] = min(points[i - 1][1],points[i][1])
        return res
class Solution(object):
    def findMinArrowShots(self, points):
        """
        :type points: List[List[int]]
        :rtype: int
        """
        #不改变原有数组
        points.sort(key = lambda x:x[0])
        count = 1
        sl = points[0][0]
        sr = points[0][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. 无重叠区间

题目链接:435. 无重叠区间
文档讲解: 代码随想录

思路:首先根据起始位置对区间进行排序。不用去想删掉哪个区间,更新右边界判断是否与下一个区间重合。

class Solution(object):
    def eraseOverlapIntervals(self, intervals):
        """
        :type intervals: List[List[int]]
        :rtype: 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]:
                #重叠
                res += 1
                #更新右边界
                intervals[i][1] = min(intervals[i - 1][1],intervals[i][1])
        return res

3.763.划分字母区间

题目链接:763.划分字母区间
文档讲解: 代码随想录

完全没思路!!!

思路:在遍历过程中,需要寻找每个字母的最远边界。主要分为两步,统计每个字母最后出现的位置;从头遍历字符串,并更新字符出现的最远下标,若最远下标与当前下标相同时,则进行切割。

class Solution(object):
    def partitionLabels(self, s):
        """
        :type s: str
        :rtype: List[int]
        """
        #统计最远距离
        last_dis = {}
        for i, char in enumerate(s):
            last_dis[char] = i 
        
        res = []
        start = 0
        end = 0
    
        #遍历字符串
        for i, char in enumerate(s):
            end = max(end, last_dis[char])
            if end == i:
                res.append(end - start + 1)
                start = i + 1
        
        return res
class Solution:
    def countLabels(self, s):
        # 初始化一个长度为26的区间列表,初始值为负无穷
        hash = [[float('-inf'), float('-inf')] for _ in range(26)]
        hash_filter = []
        for i in range(len(s)):
            if hash[ord(s[i]) - ord('a')][0] == float('-inf'):
                hash[ord(s[i]) - ord('a')][0] = i
            hash[ord(s[i]) - ord('a')][1] = i
        for i in range(len(hash)):
            if hash[i][0] != float('-inf'):
                hash_filter.append(hash[i])
        return hash_filter

    def partitionLabels(self, s):
        res = []
        hash = self.countLabels(s)
        hash.sort(key=lambda x: x[0])  # 按左边界从小到大排序
        rightBoard = hash[0][1]  # 记录最大右边界
        leftBoard = 0
        for i in range(1, len(hash)):
            if hash[i][0] > rightBoard:  # 出现分割点
                res.append(rightBoard - leftBoard + 1)
                leftBoard = hash[i][0]
            rightBoard = max(rightBoard, hash[i][1])
        res.append(rightBoard - leftBoard + 1)  # 最右端
        return res
            
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值