1.134加油站
一开始没明白为什么换起点和最终Total_tank>=0就能保证整个路途都是有油的。
比喻成债务就突然明白了,果然还是对金钱敏感一些
- 注意:真正决定汽车能否走完全程只取决于差值数组 gas-cost ,gas,cost只是中间数据
- 汽车加油--->合伙还债
- 从第一个人开始,每个人可能欠钱或者有钱
- 遇到欠钱就跳过(这里体现贪心算法思维),但计算总债务(total_tank)
- 从A有钱到B没钱了,说明A到B总体是欠钱的,跳过
- 直到找到那个最有可能cover总账的"大佬"
- 如果最后total_tank>=0,说明这群人是可以还债的,也就是大佬能平债务
- 所以要从大佬开始,就可以拿着大佬的钱去还之前跳过的债务(用盈利覆盖前面的亏损
python
class Solution:
def canCompleteCircuit(self, gas: List[int], cost: List[int]) -> int:
n = len(gas)
curr_tank = 0
total_tank = 0
start = 0
for i in range(n):
net = gas[i] - cost[i] #net gain指净收益
curr_tank += net
total_tank += net
if curr_tank < 0:
start = i + 1
curr_tank = 0
return start if total_tank >= 0 else -1
2.135分发糖果
看到这题想到了接雨水那道题,果然题解也使用了双向扫描( 因为问题中的每个位置都受到两个方向的限制,一次遍历无法确定最终值)。
正向遍历:保证右孩子评分高糖果多,反向遍历,保证左孩子评分高糖果多,两者取max求和,就是最终糖果数。
python
class Solution:
def candy(self, ratings: List[int]) -> int:
n = len(ratings)
candies = [1] * n
for i in range(1, n):
if ratings[i] > ratings[i-1]:
candies[i] = candies[i-1] + 1
for i in range(n-2, -1, -1):
if ratings[i] > ratings[i+1]:
candies[i] = max(candies[i+1] + 1, candies[i])
return sum(candies)
3.860柠檬水找零
看到题解用five和ten两个变量记录个数就行。
python
class Solution:
def lemonadeChange(self, bills: List[int]) -> bool:
change_map = {5:0,10:0,20:0}
for num in bills:
if num == 5:
change_map[5] += 1
elif num == 10:
if change_map[5] == 0:
return False
change_map[5] -= 1
change_map[10] += 1
else:
if change_map[10] != 0 and change_map[5] != 0:
change_map[10] -= 1
change_map[5] -= 1
elif change_map[10] == 0 and change_map[5] > 2:
change_map[5] -= 3
else:
return False
return True
4.406根据身高重建队列
先从高到矮排序,再插入
这样插入的时候就不会影响高个子的k值,矮个子插入的位置正好就是k值
- sort()的用法
- sort时身高从高到矮,插入时从矮到高
python
class Solution:
def reconstructQueue(self, people: List[List[int]]) -> List[List[int]]:
people.sort(key=lambda x : (-x[0], x[1]))
res = []
for p in people:
res.insert(p[1],p)
return res