Leetcode - 860
这题其实不难,而且可以尽可能的简化。首先,我们只会受到三种钱,5 ,10 ,20,收到5不用找零,找到10,找5元,收到20元,找10 +5 或者 3 * 5, 需要注意的是,因为我们根本不会用20去找零,所以我们收到多少20块钱都不是不用记录,
所以我们只有记录 5 10 的数量,也不需要用列表装载,定义两个变量计数即可,收到20,就判断5的计数变量是否大于1和10的计数变量是否大于1, 或者5的计数变量是否大于3,这里注意 我们优先找10+5的组合,因为5是更通用的,满足两种情况,所以尽可能保留5
def lemonadeChange(self, bills: List[int]) -> bool:
five, ten = 0, 0
for bill in bills:
if bill == 5:
five += 1
elif bill == 10:
if five < 1: return False
five -= 1
ten += 1
else:
if ten > 0 and five > 0:
ten -= 1
five -= 1
elif five > 2:
five -= 3
else:
return False
return True
Leetcode - 406
这题要考虑两个维度,第一是身高,第二是排位,一看到这种多维度考虑的题,就不能想着一次性把所有的都兼顾了,只能一维一维来。
首先是处理身高这个维度,因为如果对第二个维度处理,我们很难想到该怎么处理,那身高是应该什么顺序排列呢,应该从大大小排列,且碰到身高相同的,k值小的在前面。这样就造成了最大的元素都集中在了前面,这样我们再开始处理第二个维度,k值等于多少就插在第几个位置,为什么这样合理呢,因为当前元素,前面的元素一定比自己大,所以 插到指定位置后,前面的元素一定比自己大,不会存在不合理的情况,这也是为什么一开始要对身高从大到小排列的原因。
这里还有一个技巧,就是排序方法的代码,我们要定义一个类,类中的__lr__方法我们要进行重写,因为我们不仅仅是根据身高排序,碰到相同身高的还要根据k值排,
class Cmp(list):
def __lt__(self, other):
#当身高不等时,返回真实的身高大小关系,这里表示只有self的身高小于other的身高,self才小于other
if self[0] != other[0]:
return int.__lt__(self[0], other[0])
# 身高相等时,k值小的拍前面,但是因为这里我们是逆序排列的,所以这里我们符号也进行改变了
else:
return self[1] > other[1]
排序 插入 就完事了
class Cmp(list):
def __lt__(self, other):
if self[0] != other[0]:
return int.__lt__(self[0], other[0])
else:
return self[1] > other[1]
class Solution:
def reconstructQueue(self, people: List[List[int]]) -> List[List[int]]:
res = []
people.sort(key=Cmp,reverse=True)
print(people)
for item in people:
res.insert(item[1],item)
return res
Leetcode - 452
这题就是要求,一支箭要尽可能的多射几个重合区间
区间重叠有两种情况:
![](https://i-blog.csdnimg.cn/blog_migrate/7e2693857244168685e45876c63dc351.png)
数值上相邻或重叠才能使我们更好的做判断,所以我们要对一个维度进行排序,使区间尽可能的相近。
这里我们对第一个维度排序,
![](https://i-blog.csdnimg.cn/blog_migrate/695ade34c26920b1f6754d987300ccc4.png)
这里直接用卡哥的图,可以看出 只有当前的区间的右边界 >= 后一个区间的左边界时,才能视作重合,若判定为重合,则继续向下判断的时候,要使用两区间的右边界的最小值判断,比如图中1-6 2-8区间,要继续往下时,只能用6,而不是8,使用8,则和下一个区间重叠了,但是下个区间并不会与1-6重合,
所以判定重合时,边界值要更新。
我们可以用一个变量minValue来记录右边的边界。
当不等时,此时需要一个新的箭了,且将下一个元素的右边界作为新的minValue, 每来一个新箭就利用不重合那个区间的右边界来更新。
箭最少为1,所以初始化为1,且如果第一个区间出现多个重合也不会需要箭数+1
def findMinArrowShots(self, points: List[List[int]]) -> int:
points.sort(key = lambda x : x[0])
arrow = 1
minValue = points[0][1]
for i in range(len(points)-1):
if points[i+1][0] > minValue:
arrow +=1
minValue = points[i+1][1]
else:
minValue = min(points[i+1][1],minValue)
return arrow