代码随想录算法训练营 Day 25
Published:
Q1. LeetCode 134
贪心算法
class Solution:
def canCompleteCircuit(self, gas: List[int], cost: List[int]) -> int:
sum_gas = sum(gas)
sum_cost = sum(cost)
if sum_cost > sum_gas:
return -1
curr_gas = 0
idx = 0
for i in range(len(gas)):
curr_gas += gas[i] - cost[i]
if curr_gas < 0:
# 当前所累积的gas不足以满足从idx位置出发到当前位置
curr_gas = 0
idx = i + 1
return idx
全局最优解法
class Solution:
def canCompleteCircuit(self, gas: List[int], cost: List[int]) -> int:
curr_sum = 0
min_tank = float('inf')
for i in range(len(gas)):
curr_sum += gas[i] - cost[i]
if curr_sum < min_tank:
min_tank = curr_sum
# 第一种情况,开销大于补充,无法完成一圈
if curr_sum < 0:
return -1
# 第二种情况,油箱里面一直剩的油,可以从0开始
if min_tank > 0:
return 0
# 第三种情况,找到一个位置,使得从该位置出发,油箱剩余不会小于0
for i in range(len(gas) - 1, -1, -1):
min_tank += gas[i] - cost[i]
if min_tank >= 0:
return i
复杂度分析
时间复杂度:O($n$) 空间复杂度:O(1)
Q2. LeetCode 135
需要比较两边的情况,一般是将其按照一个方向确定一边,然后再反向确定另一边
class Solution:
def candy(self, ratings: List[int]) -> int:
n = len(ratings)
candy = [1] * n
# 先从左往右考虑,右孩子得分比左孩子高的情况
for i in range(1, n):
if ratings[i] > ratings[i - 1]:
candy[i] = candy[i - 1] + 1
# 再从右往左考虑,左孩子得分比右孩子高的情况
for i in range(n - 2, -1, -1):
if ratings[i] > ratings[i + 1]:
# 考虑两种情况,需要取一个最大值
candy[i] = max(candy[i], candy[i + 1] + 1)
return sum(candy)
复杂度分析
时间复杂度:O($n$) 空间复杂度:O($n$)
Q3. LeetCode 860
对于收到20的情况,优先考虑找零给10块,因为5块需要留着考虑收到10块的情况
class Solution:
def lemonadeChange(self, bills: List[int]) -> bool:
five = 0
ten = 0
for cash in bills:
if cash == 5:
five += 1
elif cash == 10:
if five:
five -= 1
ten += 1
else:
return False
else:
if ten:
ten -=1
cash -=10
while cash > 5:
cash -= 5
five -= 1
if five < 0:
return False
return True
复杂度分析
时间复杂度:O($n$) 空间复杂度:O(1)
Q4. LeetCode 406
先确定身高维度,将身高从大到小进行排序;再确定另一维度,从小到大排序
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
每次选择身高最小的人插入,需要考虑多种情况
class Solution:
def reconstructQueue(self, people: List[List[int]]) -> List[List[int]]:
people.sort(key=lambda x: (x[0], x[1]))
pos = list(range(len(people)))
res = [0] * len(people)
prev = None
c = 0
for p in people:
if prev is not None and p[0] == prev:
c += 1
idx = p[1] - c
else:
idx = p[1]
prev = p[0]
c = 0
idx = pos.pop(idx)
res[idx] = p
return res
复杂度分析
时间复杂度:O($nlogn + n^2$) 空间复杂度:O($n$)
