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

写代码的第二十六天
继续贪心贪心!!!

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

思路

最少的弓箭引爆气球,那么就是要看有没有重复覆盖的区域,如果有的话,那么一个弓箭就能引爆重复区域的气球,所以本题就是要看有多少气球是重复的,如果重复就用一根弓箭,如果不重复就加一。
解决问题1:如何判断是否有重叠部分?将这个数组按照左端点位置排序,然后按照排序后的数组查看,第i位的数组的左端点的数值是否大于第i-1位数组的右端点的值,如果大于那么就证明不存在重叠的情况,弓箭数加一,否则就是重叠的。
解决问题2:题中没有说最多两个气球重叠,所以很有可能出现好几个气球是重叠的。就比如说i-1位和i位是重叠的,那i+1位是否和i-1和i的重叠部分也重叠的呢?我们思考一下i-1位和i位的重叠位置是i-1位的右下标到i位的左下标这个范围,那么就是说如果i+1位的左下标在上面的范围里面就证明他们仨重叠!所以i+1位的左下标只要小于等于i-1位的右下标即可。所以在这里我们要做的就是每次比较之后都更新右边界,也就是右下标,上面是举了个例子,但是代码要写普适性的代码,所以遍历的时候要保留每次的当前结点的右边界和上一位结点的右边界的最小值,这样在比较下一个结点的时候,直接和这个右边界进行比较,就可以走之前的if步骤的流程了,让当前结点的左边界和保留的最小右边界进行比较。
正确代码

class Solution:
    def findMinArrowShots(self, points: List[List[int]]) -> int:
        if len(points) == 0:
            return 0
        result = 1
        points = sorted(points,key=lambda x: (x[0], x[1]))
        for i in range(len(points)):
            if points[i][0] > points[i-1][1]:
                result += 1
            else:
                points[i][1] = min(points[i-1][1],points[i][1])
        return result

435. 无重叠区间

思路

本题和上面的题思路和注意点是一致的,只不过本题是要找到重叠区间,查看有几个重叠区间,所以初始化重叠区间为count=0,然后按照左下标进行从小到大的排序,排序后开始判断是否有重叠部分,按照上一道题的思路第i位的数组的左端点的数值是否大于第i-1位数组的右端点的值,如果大于那么就证明不存在重叠的情况,否则就存在重叠情况,count+=1;还有一个问题如果下面的数组的范围也在上面的重叠区间呢?和上一道题一样,我们记录每次重叠出现的最小右边界,这样如果接下来的数组左下标小于这个右下标就证明存在重叠,就回到了if的判断条件中了。
正确代码

class Solution:
    def eraseOverlapIntervals(self, intervals: List[List[int]]) -> int:
        intervals = sorted(intervals,key=lambda x: (x[0], x[1]))
        count = 0
        for i in range(len(intervals)):
            if i > 0 and intervals[i][0] < intervals[i-1][1]:
                count += 1 
                intervals[i][1] = min(intervals[i][1],intervals[i-1][1])
        return count

763.划分字母区间

思路

本题要找的是字母的子区间并且顺序不能变,每个区间要包含这个字符串中出现字符的全部,比如说有a那就要包括这个s字符串中的所有a,一点思路也没有,直接看视频。。。
首先,建立哈希表,这个哈希表是用来存储s字符串中每个字符出现的最远的下标,这样就能在遍历s字符串的时候知道在s字符串中个子字符串的最远下标;其次我们要找的是每个子串的长度,所以需要知道每个子串的左端点left和右端点right,append进result的就是right-left+1,下一个left的位置就是之前子串的right+1;所以我们会发现需要判断的就是right的值,right值其实就是每遍历一个s中的字符都去看这个字符的最远位置在哪,如果该字符的最远位置和当前i的位置一致那么此时一个子串已经出来了;如果不一致那么就要每次的right值都更新为当前字符的最远距离和之前的right值最大的那个。
正确代码

class Solution:
    def partitionLabels(self, s: str) -> List[int]:
        hashtable = {}        
        for i in range(len(s)):
            hashtable[ord(s[i])-ord('a')] = i
        result = []
        left = 0
        right = 0
        for i in range(len(s)):
            right = max(hashtable[ord(s[i])-ord('a')],right)
            if right == i:
                result.append(right-left+1)
                left = i + 1
        return result
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值