Day21:贪心算法 | 加油站,分发糖果

1.134加油站

一开始没明白为什么换起点和最终Total_tank>=0就能保证整个路途都是有油的。

比喻成债务就突然明白了,果然还是对金钱敏感一些

  1. 注意:真正决定汽车能否走完全程只取决于差值数组 gas-cost ,gas,cost只是中间数据
  2. 汽车加油--->合伙还债
    1. 从第一个人开始,每个人可能欠钱或者有钱
    2. 遇到欠钱就跳过(这里体现贪心算法思维),但计算总债务(total_tank)
    3. 从A有钱到B没钱了,说明A到B总体是欠钱的,跳过
    4. 直到找到那个最有可能cover总账的"大佬"
      1. 如果最后total_tank>=0,说明这群人是可以还债的,也就是大佬能平债务
      2. 所以要从大佬开始,就可以拿着大佬的钱去还之前跳过的债务(用盈利覆盖前面的亏损
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值

  1. sort()的用法
  2. 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
相关推荐
点云侠2 小时前
粒子群优化算法求解三维变换矩阵的数学推导
线性代数·算法·矩阵
dragoooon342 小时前
[hot100 NO.31~36]
数据结构·算法·排序算法
白兰地空瓶2 小时前
JavaScript 列表转树(List to Tree)详解:前端面试中如何从递归 O(n²) 优化到一次遍历 O(n)
javascript·算法·面试
艾醒2 小时前
大模型原理剖析——从技术特性、底层架构到落地逻辑的全维度解析
算法
Liangwei Lin3 小时前
洛谷 B3637 最长上升子序列
算法
珂朵莉MM3 小时前
第七届全球校园人工智能算法精英大赛-算法巅峰赛产业命题赛第一赛季优化题--无人机配送
人工智能·算法·无人机
xiaoxue..3 小时前
列表转树结构:从扁平列表到层级森林
前端·javascript·算法·面试
代码游侠3 小时前
复习——线程(pthread)
linux·运维·开发语言·网络·学习·算法
papaofdoudou3 小时前
基于QEMU 模拟intel-iommu的sva/svm demo环境搭建和验证
算法·机器学习·支持向量机