day35| 860+406+452

发布时间 2023-04-21 14:33:41作者: blueCP1999

860. 柠檬水找零

 

题目简述:

在柠檬水摊上,每一杯柠檬水的售价为 5 美元。顾客排队购买你的产品,(按账单 bills 支付的顺序)一次购买一杯。

每位顾客只买一杯柠檬水,然后向你付 5 美元、10 美元或 20 美元。你必须给每个顾客正确找零,也就是说净交易是每位顾客向你支付 5 美元。

注意,一开始你手头没有任何零钱。

给你一个整数数组 bills ,其中 bills[i] 是第 i 位顾客付的账。如果你能给每位顾客正确找零,返回 true ,否则返回 false 。

 

思路:

1. 用哈希表

2. 另外注意,找零为15的时候,我们更倾向于以10+5的形式把钱找出来,而不是给5+5+5的形式

3. 这是因为,5+5+5的形式很容易把5的数量都给用完,这是如果顾客给你10,你就没有5可找了

 

代码如下:

class Solution:
    def lemonadeChange(self, bills: List[int]) -> bool:
        dict={}
        dict['five']=0
        dict['ten']=0

        for bill in bills:
            if bill==5:
                dict['five']+=1
            if bill==10:
                if dict['five']>=1:
                    dict['five']-=1
                    dict['ten']+=1
                else:
                    return False
            if bill==20:
                if dict['five']>=1 and dict['ten']>=1:
                    dict['five']-=1
                    dict['ten']-=1
                elif dict['five']>=3:
                    dict['five']-=3
                else:
                    return False
        
        return True

 

 

406. 根据身高重建队列

 

题目简述:

假设有打乱顺序的一群人站成一个队列,数组 people 表示队列中一些人的属性(不一定按顺序)。每个 people[i] = [hi, ki] 表示第 i 个人的身高为 hi ,前面 正好 有 ki 个身高大于或等于 hi 的人。

请你重新构造并返回输入数组 people 所表示的队列。返回的队列应该格式化为数组 queue ,其中 queue[j] = [hj, kj] 是队列中第 j 个人的属性(queue[0] 是排在队列前面的人)。

 

思路:

1. 先将打乱的数组身高从大小下排列

2. 身高一致的情况下,按ki大小从小到大排列

3. 然后从左至右遍历排好序的数组

4. 依次取数,根据ki确定位置

5. 取到后面的person时,前面已经排好,此时即使把person放到前面的人之间,也不会使得前面人的ki的正确性

 

代码如下:

class Solution:
    def reconstructQueue(self, people: List[List[int]]) -> List[List[int]]:
        people.sort(key=lambda x: (-x[0], x[1]))
        n = len(people)
        ans = list()
        for person in people:
            print(person[1])
            
            # 这是一种插入的方法,如果person[1]==1,等于是在下标0-1之间插入了一个数
            ans[person[1]:person[1]] = [person]
            print(ans[person[1]:person[1]])
        return ans

 

 

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

 

题目简述:

有一些球形气球贴在一堵用 XY 平面表示的墙面上。墙面上的气球记录在整数数组 points ,其中points[i] = [xstart, xend] 表示水平直径在 xstart 和 xend之间的气球。你不知道气球的确切 y 坐标。

一支弓箭可以沿着 x 轴从不同点 完全垂直 地射出。在坐标 x 处射出一支箭,若有一个气球的直径的开始和结束坐标为 xstart,xend, 且满足  xstart ≤ x ≤ xend,则该气球会被 引爆 。可以射出的弓箭的数量 没有限制 。 弓箭一旦被射出之后,可以无限地前进。

给你一个数组 points ,返回引爆所有气球所必须射出的 最小 弓箭数 。

 

 

思路:

1. 按气球右边界从小到大排序

2. 令箭在排序后第一个气球的右边界

3. 因为第二个气球排在后面,那么第二个气球的右边界一定大于第一个气球的右边界

4. 这样一来,如果此时箭的位置大于第二个气球的左边界,那么箭也能射爆第二个气球,不用增加箭矢

5. 继续比较第三个气球的左边界与箭矢位置。如果第三个气球的左边界大于箭矢位置,则需要加一只箭矢,把新箭矢放在第三个气球的右边界上

6. 以此类推

 

代码如下:

class Solution:
    def findMinArrowShots(self, points: List[List[int]]) -> int:
        if not points:
            return 0
        
        points.sort(key=lambda balloon: balloon[1])
        pos = points[0][1]
        ans = 1
        for balloon in points:
            if balloon[0] > pos:
                pos = balloon[1]
                ans += 1
        
        return ans