134.加油站
变量curSum记录当前的剩余油量总和,如果小于0,那么意味着这段路每个节点都不可以作为起点。
变量preSum记录整个路径上的总剩余量,如果小于0,意味着不管起点在哪你都走不回来。
class Solution:
def canCompleteCircuit(self, gas: List[int], cost: List[int]) -> int:
n=len(gas);preSum=0;i=0;start=0
curSum=0
while i < n:
curSum+=gas[i]-cost[i]
preSum+=gas[i]-cost[i]
if curSum<0: #走过的这段距离都不足以支撑汽车
start=i+1
curSum=0
i+=1
if preSum<0:
return -1
return start
135.分发糖果
class Solution:
def candy(self, ratings: List[int]) -> int:
"""
先顾住一个方向,再去考虑另一个方向
"""
n=len(ratings)
nums=[1]*n
for i in range(n-1): #先来比较是不是右边大于左边
if ratings[i+1]>ratings[i]:
nums[i+1]=nums[i]+1
#现在顾好一头了,现在我们来看另外一头
for i in range(n-1,0,-1):
if ratings[i-1]>ratings[i]:
nums[i-1]=max(nums[i-1],nums[i]+1)
return sum(nums)
此处要注意nums[i+1]=nums[i]+1,不能写成nums[i+1]+=1
+=1会在多次调整中导致数值异常,而num[i]+1可以保证当前值精确依赖前一个值(即与题目中的要求相符)
860.柠檬水找零
挺简单,但这感觉不是贪心算法。。。。
class Solution:
def lemonadeChange(self, bills: List[int]) -> bool:
hand_money={"5":0,"10":0,"15":0}
for i in range(len(bills)):
if bills[i]==5:
hand_money["5"]+=1
if bills[i]==10:
if hand_money["5"]>0:
hand_money["5"]-=1
hand_money["10"]+=1
else: return False
if bills[i]==20:
if hand_money["10"]>0 and hand_money["5"]>0:
hand_money["10"]-=1
hand_money["5"]-=1
elif hand_money["5"]>2:
hand_money["5"]-=3
else:
return False
return True
406.根据身高重建队列
本题收获:这道题其实和分发糖果有相似之处,都是要先顾住一边,再看另一个因素。
本题是先根据身高来进行排序(前面的节点一定比本节点高),然后再根据k进行排序即可。
在python中可以使用lambda表达式,让这个过程变得简单。
按照身高排序之后,优先按身高高的people的k来插入,后序插入节点也不会影响前面已经插入的节点,最终按照k的规则完成了队列。
class Solution:
def reconstructQueue(self, people: List[List[int]]) -> List[List[int]]:
people.sort(key=lambda x:[-x[0],x[1]])
que=[]
for p in people:
que.insert(p[1],p)
return que