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
相关推荐
无限进步_32 分钟前
【C++&string】大数相乘算法详解:从字符串加法到乘法实现
java·开发语言·c++·git·算法·github·visual studio
苏纪云1 小时前
蓝桥杯考前突击
c++·算法·蓝桥杯
W23035765731 小时前
经典算法详解:最长公共子序列 (LCS) —— 从暴力递归到动态规划完整实现
算法·动态规划·最长子序列
pzx_0011 小时前
【优化器】 随机梯度下降 SGD 详解
人工智能·python·算法
小肝一下1 小时前
每日两道力扣,day8
c++·算法·leetcode·哈希算法·hot100
无限进步_1 小时前
【C++】验证回文字符串:高效算法详解与优化
java·开发语言·c++·git·算法·github·visual studio
Meme Buoy2 小时前
18.补充数学1:生成树-最短路径-最大流量-线性规划
数据结构·算法
paeamecium2 小时前
【PAT甲级真题】- Count PAT‘s (25)
c++·算法·动态规划·pat考试·pat
汀、人工智能2 小时前
[特殊字符] 第89课:岛屿数量
数据结构·算法·数据库架构·图论·bfs·岛屿数量
九英里路2 小时前
cpp容器——string模拟实现
java·前端·数据结构·c++·算法·容器·字符串