文章目录
- [LeetCode:134. 加油站](#LeetCode:134. 加油站)
- [LeetCode:135. 分发糖果](#LeetCode:135. 分发糖果)
- [LeetCode:860. 柠檬水找零](#LeetCode:860. 柠檬水找零)
- [LeetCode:406. 根据身高重建队列](#LeetCode:406. 根据身高重建队列)
LeetCode:134. 加油站
https://leetcode.cn/problems/gas-station/
思路
- 首先,计算每个加油站的净收益,得到全程的总剩余油量:
(1)如果为负数,则总油量不足以支撑全程,返回 -1。
(2)如果不为负数,则一定存在一个可行的起点。 - 初始化
cur_gas = 0表示当前累计的剩余油量,start = 0表示当前试探的起点。
从i = 0开始遍历每个加油站,将diff[i]累加到cur_gas:
(1)如果cur_gas始终非负,说明从当前起点出发能顺利到达当前位置。
(2)如果cur_gas < 0,意味着从起点到当前位置i这一段路程无法完成。此时,将起点设为i + 1,并将cur_gas重置为 0,继续向后试探。
【原因 :说明此时起点start到i的累计净收益为负。那么对于任意一个介于start和i之间的点k,从k出发到i的累计净收益也必然为负。因为从start到k的累计净收益是非负的,否则在更早之前就会重置起点。】
解答
python
class Solution:
def canCompleteCircuit(self, gas: List[int], cost: List[int]) -> int:
diff = [] # 记录每个加油站到下一个加油站剩余油的的净含量
n = len(gas)
gas_remain = 0
for i in range(n):
gas_remain += gas[i] - cost[i]
diff.append(gas[i] - cost[i])
if gas_remain < 0: # 如果所有加油站油小于总耗油量,则无法成环
return -1
cur_gas = 0
start = 0
for i in range(n):
cur_gas += diff[i]
if cur_gas < 0:
start = i + 1
cur_gas = 0
return start
LeetCode:135. 分发糖果
https://leetcode.cn/problems/candy/description/
思路
通过两次遍历来满足条件。
- 每个孩子先发 1 颗糖果。
- 从左向右遍历:确保当右边孩子评分高于左边时,右边孩子的糖果数大于左边。
当ratings[i] > ratings[i-1],则candies[i] = candies[i-1] + 1。 - 从右向左遍历:确保当左边孩子评分高于右边时,左边孩子的糖果数大于右边。
当ratings[i] > ratings[i+1],则candies[i] = max(candies[i], candies[i+1] + 1)。
解答
python
class Solution:
def candy(self, ratings: List[int]) -> int:
n = len(ratings)
candies = [1] * n # 每个孩子至少1颗糖果
# 从左到右
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], candies[i+1] + 1)
return sum(candies)
LeetCode:860. 柠檬水找零
https://leetcode.cn/problems/lemonade-change/
思路
尽可能用 10 找零。如果找零时 5 不足,则无法找零。
解答
python
class Solution:
def lemonadeChange(self, bills: List[int]) -> bool:
five = 0
ten = 0
for bill in bills:
if bill == 5: # 收5,不用找零
five += 1
elif bill == 10: # 收10,只能用5找零
five -= 1
ten += 1
else: # 收20,可以用5、10找零,优先用10
if ten > 0:
five -= 1
ten -= 1
else:
five -= 3
if five < 0: # 改顾客无法找零
return False
return True
LeetCode:406. 根据身高重建队列
https://leetcode.cn/problems/queue-reconstruction-by-height/
思路
- 先将
people按照身高降序、k升序排列。 - 遍历排序后的
people,对于每个人[h, k],将其插入到queue的索引k处。因为此时queue中已有的所有人身高都 >= 当前人的身高,所以当前人插入到位置 k 后,他前面正好有 k 个人身高都 >= 他。
解答
python
class Solution:
def reconstructQueue(self, people: List[List[int]]) -> List[List[int]]:
people.sort(key=lambda x: (-x[0], x[1])) # 身高降序,k升序
queue = []
for p in people:
# 插入到索引 p[1] 的位置
queue.insert(p[1], p)
return queue