代码随想录算法训练营第二十九天 |贪心算法part03
134 加油站
思路:分成两步,第一步是看当前油量,第二步看总油量。
当前油量如果小于0,那么肯定就不能从这次的开头开始。如果总油量小于0,说明走不完。
curgas = 0
totalgas = 0
start = 0
for i in range(len(gas)):
curgas += gas[i] - cost[i]
totalgas += gas[i] - cost[i]
if curgas < 0 :
start = i + 1
curgas = 0
if totalgas < 0 :
return -1
return start
135 分发糖果
思路:分成两次发,第一次从左往右发,第二次从右往左发。
ratings = [1,2,87,87,87,2,1]
candys = [1] * len(ratings)
# 从左往右数,左边的比右边的小
for i in range(1,len(ratings)):
if ratings[i] > ratings[i-1] :
candys[i] = candys[i-1] + 1
print(candys)
# 从右往左数,左边的比右边的大
for i in range(len(ratings)-2,-1,-1):
if ratings[i] > ratings[i+1] :
# print(i,candys)
candys[i] = max(candys[i],candys[i+1]+1)
print(candys)
print(sum(candys))
860 柠檬水找零
思路:这道题目很简单,直接记录每一种钞票对应的数量就可以了。
bills = [5,5,10,10,20]
five = 0
ten = 0
twenty = 0
for i in bills:
if i == 5:
five += 1
elif i == 10:
five -= 1
ten += 1
elif i == 20:
if ten > 0 and five > 0:
ten -= 1
five -= 1
else:
five -= 3
if five < 0 or ten < 0:
print(False)
print(True)
406 根据身高重建队列
思路:列表中元素的第一位是身高,第二位是前面的人身高比他高或一样高的人数。 所以这道题目就转换成了按照第二位进行排序的问题。 首先根据身高进行排序,如果身高相同,那么第二位小的排在前面。 其次按照上一步的列表进行插入到新的列表。
按照身高排序之后,优先按身高高的people的k来插入,后序插入节点也不会影响前面已经插入的节点,最终按照k的规则完成了队列。
也就是按照排序后的列表的第二位进行插入,按顺序遍历该列表,插入到新的列表的位置(索引)就是对应的第二位
所以在按照身高从大到小排序后:
局部最优:优先按身高高的people的k来插入。插入操作过后的people满足队列属性
全局最优:最后都做完插入操作,整个队列满足题目队列属性
insert(i,j) :在索引为i处插入元素j
people.sort(key=lambda x: (-x[0], x[1]))
people.sort(key=lambda x: (x[0],-x[1]), reverse=True)
que = []
for p in people:
que.insert(p[1], p)
return que