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
相关推荐
-dzk-1 天前
【代码随想录】LC 59.螺旋矩阵 II
c++·线性代数·算法·矩阵·模拟
风筝在晴天搁浅1 天前
hot100 78.子集
java·算法
Jasmine_llq1 天前
《P4587 [FJOI2016] 神秘数》
算法·倍增思想·稀疏表(st 表)·前缀和数组(解决静态区间和查询·st表核心实现高效预处理和查询·预处理优化(提前计算所需信息·快速io提升大规模数据读写效率
超级大只老咪1 天前
快速进制转换
笔记·算法
m0_706653231 天前
C++编译期数组操作
开发语言·c++·算法
故事和你911 天前
sdut-Java面向对象-06 继承和多态、抽象类和接口(函数题:10-18题)
java·开发语言·算法·面向对象·基础语法·继承和多态·抽象类和接口
qq_423233901 天前
C++与Python混合编程实战
开发语言·c++·算法
TracyCoder1231 天前
LeetCode Hot100(19/100)——206. 反转链表
算法·leetcode
m0_715575341 天前
分布式任务调度系统
开发语言·c++·算法