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
相关推荐
BothSavage14 小时前
Trae远程开发中DeepSeek自定义模型4054错误的排查与修复
算法
小林ixn14 小时前
从暴力到KMP:一道题彻底搞懂字符串匹配的前世今生
算法
烬羽15 小时前
字符串算法入门:从反转字符串到回文判断,面试不再慌
算法·面试
先吃饱再说1 天前
判断回文字符串,从一行代码到双指针优化
算法
黄敬峰1 天前
深入理解算法核心:从递归思想、数组扁平化到快速排序
算法
得物技术1 天前
从狂野代码到按目标生产:得物推荐 AI Harness 的工程化实践|AICon 演讲整理
人工智能·算法·架构
AI小老六2 天前
SkillOpt 架构拆解:把 Skill 文本当参数,用执行轨迹训练 Agent
后端·算法·ai编程
胡萝卜术2 天前
从“分数打架”到“排名投票”:为什么你的ChatBI必须用RRF?
算法·设计模式·面试
Asize2 天前
初识DFS 与 BFS:递归、队列与图遍历
算法