860.柠檬水找零
思路
局部最优:遇到账单20,优先消耗美元10,完成本次找零。全局最优:完成全部账单的找零。
因为美元10只能给账单20找零,而美元5可以给账单10和账单20找零,美元5更万能!
代码
class Solution:
def lemonadeChange(self, bills: List[int]) -> bool:
ten = 0
five = 0
for i in bills:
if i == 5:
five += 1
if i == 10:
if five == 0:
return False
else:
five -= 1
ten += 1
if i == 20:
# 没有10美元那就用5美元找零
if ten == 0:
if five < 3:
return False
else:
five -= 3
# 有10美元就处理掉10美元
else:
if five < 1:
return False
else:
five -= 1
ten -= 1
return True
复杂度分析
- 时间复杂度:
O(n)
- 空间复杂度:
O(1)
406.根据身高重建队列
思路
在按照身高从大到小排序后:
局部最优:优先按身高高的people的k来插入。插入操作过后的people满足队列属性
全局最优:最后都做完插入操作,整个队列满足题目队列属性
代码
代码非常简介:
class Solution:
def reconstructQueue(self, people: List[List[int]]) -> List[List[int]]:
# 注意sort的方法
people.sort(key = lambda x:(-x[0], x[1]))
res = []
for i in people:
res.insert(i[1], i)
return res
在使用元组作为key来排序的时候,首先根据元组第一个元素进行排序,遇到
452. 用最少数量的箭引爆气球
思路
为了让气球尽可能的重叠,需要对数组进行排序。
要点
每次发现有重叠的区间时,在进入下一次循环之前需要更新最小的右边界。
代码
class Solution: # 改变原数组
def findMinArrowShots(self, points: List[List[int]]) -> int:
points.sort(key = lambda x: x[0])
count = 1
for i in range(1, len(points)):
# 气球i和气球i-1不挨着,注意这里不是>=
if points[i][0] > points[i-1][1]:
count += 1
# 如果重叠区间,需要更新右边界
else:
points[i][1] = min(points[i][1], points[i-1][1])
return count
class Solution: # 不改变原数组
def findMinArrowShots(self, points: List[List[int]]) -> int:
points.sort(key = lambda x: x[0])
sr = points[0][1]
count = 1
for i in points:
if i[0]>sr:
count+=1
sr = i[1]
else:
sr = min(sr,i[1])
return count
复杂度分析
- 时间复杂度:
O(nlog n)
,因为有一个排序 - 空间复杂度:
O(1)