代码随想录27期|Python|Day34|贪心算法|860.柠檬水找零|406.根据身高重建队列|452. 用最少数量的箭引爆气球

文章介绍了三个编程问题的解决方案:柠檬水找零通过管理5¥和10¥硬币;根据身高重建队列涉及两维排序;用最少箭引爆气球则关注气球覆盖的优化。
摘要由CSDN通过智能技术生成

 860.柠檬水找零

只要遵循基本的策略即可:

1、遇到5¥的直接收下并记录;

2、遇到10¥的看看有没有5¥的,有的话减少1张5¥,记录1张10¥;

3、遇到20¥有两种情况:

        1,手里有10¥和5¥的,直接找即可(5¥既可以找20¥又可以找10¥,所以尽量少消耗5¥);

        2,手里有3张以上的5¥。

4、上述遇到找不开的返回false。

从头到尾遍历一遍数组,全部通过上述情况,返回true。

class Solution(object):
    def lemonadeChange(self, bills):
        """
        :type bills: List[int]
        :rtype: bool
        """
        five, ten = 0, 0  # 20¥不需要记录,因为不用它找零
        for bill in bills:
            if bill == 5:  # 如果是5¥,直接收下
                five += 1
            elif bill == 10:
                if five == 0:  # 如果没有5¥的直接返回false
                    return False
                else:  # 如果有5¥的,用5¥的找然后记录10¥的
                    five -= 1
                    ten += 1
            else: 
                if ten > 0 and five > 0:  # 如果既有5¥又有10¥,那就优先使用这种组合
                    ten -= 1
                    five -= 1
                elif five >= 3:  # 如果没有10¥且有3张5¥,也可以
                    five -= 3
                else:
                    return False
        # 以上都满足且没有返回false就说明可以找开
        return True

 406.根据身高重建队列

本题和分发糖果在解法上都是相似的,都是遍历两遍,第一遍处理一个纬度的排序,第二遍处理另一个纬度的排序。

1、第一遍,首先先按照身高从大到小排序,对于身高相同的元素,按照k值从小到大排序;

        ps.这里lambda需要注意一下写法,正常的sort是默认从小到大进行排序。

2、第二遍,遍历整个数组,按照排序好的新数组的k值插入到相应的下标位置。

class Solution(object):
    def reconstructQueue(self, people):
        """
        :type people: List[List[int]]
        :rtype: List[List[int]]
        """
        # 先排列整个数组
        people.sort(key=lambda x:(-x[0], x[1]))  
        # lambda表达式内部的含义是:先比较变量的第一个值,再比较元素的第二个值
        que = []  # 创建一个新的队列用于插入

        for p in people:
            que.insert(p[1], p)  # 按照排列好的元素的k值插入到相应的下标

        return que

这里需要学习一下sort比较的key值的定义:对于传入参数是元组的参数,首先按照元组的第一个位置进行比较,在第一个位置相同的条件下再按照元组的第二个位置进行比较。

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

本题在于对于题目意图的转化:

1、首先对于气球进行排序,标准是按照左边界从小到大排序,所以只需要考虑右边界;

        这里需要掌握lamda的写法;

2、从头到尾遍历气球,出现两种情况:

        1,前一个的右边界在当前左边界的左边,也就是小于,说明不重合,res++;

        2,前一个的右边界在当前气球左边界的右边(大于等于),说明重合,不需要累加弓箭数量,但是需要更新当前气球的右边界是二者右边界的最小值。

3、返回res。

class Solution(object):
    def findMinArrowShots(self, points):
        """
        :type points: List[List[int]]
        :rtype: int
        """
        if len(points) == 0:  # 如果气球数量是0,直接返回0
            return 0
        points.sort(key=lambda x: x[0])  # 按照气球左边界从小到大排序
        res = 1  # 初始化
        for i in range(1, len(points)):  # 注意是从1开始
            if points[i-1][1] < points[i][0]:  # 如果当前气球的左边界比上一个气球的右边界大,说明不存在重叠区域
                res += 1
            else:  # 其他情况说明有重叠,更新当前气球的右边界是二者的最小值
                points[i][1] = min(points[i-1][1], points[i][1])
        return res

第34天完结!! 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值