代码随想录算法训练营第三十五天|860.柠檬水找零, 406.根据身高重建队列,452. 用最少数量的箭引爆气球
860.柠檬水找零
题目链接:柠檬水找零
暴力解法
没碰到给20的正常比还剩几张5块,碰到给20的,先看还有没有一张5块和一张10块(先消耗10块),没有再去看没有没有三张5块。
行吧这就是贪心算法。。。用了都不知道自己用了。
class Solution:
def lemonadeChange(self, bills: List[int]) -> bool:
pay = defaultdict(int)
for i in range(len(bills)):
need = bills[i]-5
if need != 15:
if int(need/5) > pay[5]:
print(1)
return False
else:
pay[5] -= int(need/5)
else:
if (pay[5] > 0 and pay[10] > 0):
pay[5] -= 1
pay[10] -= 1
elif pay[5] > 2:
pay[5] -= 3
else:
return False
pay[bills[i]] += 1
return True
406.根据身高重建队列
题目链接:根据身高重建队列
关于排序
整理一下排序的办法
基本语法
list.sort(key,reverse=False)
sorted(list,key,reverse=False)
reverse=False
指的是升序key
是按照什么排序list.sort()
是没有输出的,直接对list修改sorted(list)
输出就是排序完的数列
key
- 按照某一位排序
sorted(a, key=lambda x: x[0])
a.sort(key=lambda x: x[0])
- 也可以写两维,先按一维排序,如果相同按第二味道排
sorted(a, key=lambda x: (x[1], x[0]))
a.sort(key=lambda x: (x[1], x[0]))
itemgetter
和attrgetter
itemgetter
控制的是第几维度,也可以写括号
attrgetter
控制的是名字,但前提是要命名
class Student:
def __init__(self, name, grade, age):
self.name = name
self.grade = grade
self.age = age
def __repr__(self):
return repr((self.name, self.grade, self.age))
student_objects = [
Student('john', 'A', 15),
Student('jane', 'B', 12),
Student('dave', 'B', 10),
]
sorted(student_tuples, key=itemgetter(2))
[('dave', 'B', 10), ('jane', 'B', 12), ('john', 'A', 15)]
sorted(student_objects, key=attrgetter('age'))
[('dave', 'B', 10), ('jane', 'B', 12), ('john', 'A', 15)]
解答
这道题是需要第一维降序,第二维升序的
可以用的办法
people.sort(key=lambda x:(x[0],-x[1]),reverse=True)
这道题的要点就是按照身高排完之后,后面的k更小的人,就可以直接插到他k的位置,因为后面已经没有比他更高的人了,所以即使后面的要插到k位置的前面,也无所谓,因为都更矮,所以不用算。
class Solution:
def reconstructQueue(self, people: List[List[int]]) -> List[List[int]]:
people.sort(key=lambda x:(x[0],-x[1]),reverse=True)
#print(people)
s = []
for i in range(len(people)):
if people[i][1] == len(s):
s.append(people[i])
elif people[i][1] < len(s):
s.insert(people[i][1],people[i])
return s
452. 用最少数量的箭引爆气球
题目链接:用最少数量的箭引爆气球
稍微有点想法,但不知道怎么实现,不过确实没想到排序,这样只要管一遍就行了。
这道题的想法就是,排序完了之后,如果现在的这个气球的左边界比上一个气球的右边界还大的话,那这两个气球必不重合,那一定要加1,但如果小于等于的话,就更新当前气球的左边界,接着去和后面的气球作比较。
class Solution:
def findMinArrowShots(self, points: List[List[int]]) -> int:
points.sort(key=lambda x: x[0])
#print(points)
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], points[i-1][1])
return res