贪心算法part03

134 加油站

在一条环路上有 N 个加油站,其中第 i 个加油站有汽油 gasi 升。

你有一辆油箱容量无限的的汽车,从第 i 个加油站开往第 i+1 个加油站需要消耗汽油 costi 升。你从其中的一个加油站出发,开始时油箱为空。

如果你可以绕环路行驶一周,则返回出发时加油站的编号,否则返回 -1。

python 复制代码
class Solution:
    def canCompleteCircuit(self, gas: List[int], cost: List[int]) -> int:
        for i in range(len(cost)):
            rest = gas[i] - cost[i]  # 记录剩余油量
            index = (i + 1) % len(cost)  # 下一个加油站的索引

            while rest > 0 and index != i:  # 模拟以i为起点行驶一圈(如果有rest==0,那么答案就不唯一了)
                rest += gas[index] - cost[index]  # 更新剩余油量
                index = (index + 1) % len(cost)  # 更新下一个加油站的索引

            if rest >= 0 and index == i:  # 如果以i为起点跑一圈,剩余油量>=0,并且回到起始位置
                return i  # 返回起始位置i

        return -1  # 所有起始位置都无法环绕一圈,返回-1

135 分发糖果

老师想给孩子们分发糖果,有 N 个孩子站成了一条直线,老师会根据每个孩子的表现,预先给他们评分。

你需要按照以下要求,帮助老师给这些孩子分发糖果:

每个孩子至少分配到 1 个糖果。

相邻的孩子中,评分高的孩子必须获得更多的糖果。

那么这样下来,老师至少需要准备多少颗糖果呢?

python 复制代码
class Solution:
    def candy(self, ratings: List[int]) -> int:
        candyVec = [1] * len(ratings)
        
        # 从前向后遍历,处理右侧比左侧评分高的情况
        for i in range(1, len(ratings)):
            if ratings[i] > ratings[i - 1]:
                candyVec[i] = candyVec[i - 1] + 1
        
        # 从后向前遍历,处理左侧比右侧评分高的情况
        for i in range(len(ratings) - 2, -1, -1):
            if ratings[i] > ratings[i + 1]:
                candyVec[i] = max(candyVec[i], candyVec[i + 1] + 1)
        
        # 统计结果
        result = sum(candyVec)
        return result

860 柠檬水找零

在柠檬水摊上,每一杯柠檬水的售价为 5 美元。

顾客排队购买你的产品,(按账单 bills 支付的顺序)一次购买一杯。

每位顾客只买一杯柠檬水,然后向你付 5 美元、10 美元或 20 美元。你必须给每个顾客正确找零,也就是说净交易是每位顾客向你支付 5 美元。

注意,一开始你手头没有任何零钱。

如果你能给每位顾客正确找零,返回 true ,否则返回 false 。

python 复制代码
class Solution:
    def lemonadeChange(self, bills: List[int]) -> bool:
        five = 0
        ten = 0
        twenty = 0
        
        for bill in bills:
            # 情况一:收到5美元
            if bill == 5:
                five += 1
            
            # 情况二:收到10美元
            if bill == 10:
                if five <= 0:
                    return False
                ten += 1
                five -= 1
            
            # 情况三:收到20美元
            if bill == 20:
                # 先尝试使用10美元和5美元找零
                if five > 0 and ten > 0:
                    five -= 1
                    ten -= 1
                    #twenty += 1
                # 如果无法使用10美元找零,则尝试使用三张5美元找零
                elif five >= 3:
                    five -= 3
                    #twenty += 1
                else:
                    return False
        
        return True

406 根据身高重建队列

假设有打乱顺序的一群人站成一个队列,数组 people 表示队列中一些人的属性(不一定按顺序)。每个 peoplei = hi, ki 表示第 i 个人的身高为 hi ,前面 正好 有 ki 个身高大于或等于 hi 的人。

请你重新构造并返回输入数组 people 所表示的队列。返回的队列应该格式化为数组 queue ,其中 queuej = hj, kj 是队列中第 j 个人的属性(queue0 是排在队列前面的人)。

python 复制代码
class Solution:
    def reconstructQueue(self, people: List[List[int]]) -> List[List[int]]:
    	# 先按照h维度的身高顺序从高到低排序。确定第一个维度
        # lambda返回的是一个元组:当-x[0](维度h)相同时,再根据x[1](维度k)从小到大排序
        people.sort(key=lambda x: (-x[0], x[1]))
        que = []
	
	# 根据每个元素的第二个维度k,贪心算法,进行插入
        # people已经排序过了:同一高度时k值小的排前面。
        for p in people:
            que.insert(p[1], p)
        return que
相关推荐
kebidaixu25 分钟前
两轮BMS 防打火策略详解
算法
wabs6661 小时前
关于动态规划【力扣1035.不相交的线和53.最大子数组和的思考】
算法·leetcode·动态规划
退休倒计时1 小时前
【每日一题】LeetCode 199. 二叉树的右视图 TypeScript
算法·leetcode·typescript
可编程芯片开发1 小时前
通过MATLAB实现PID控制器,积分分离控制器以及滑模控制器
算法
kebidaixu2 小时前
两轮BMS 短路保护策略详解
算法
ylscode2 小时前
微软推送KB5095189:Windows 11 OOBE开箱即用体验迎来新一轮优化
windows·microsoft
zwenqiyu2 小时前
非线性字符串数据结构串讲
数据结构·c++·学习·算法
z小猫不吃鱼2 小时前
03 Optimal Brain Surgeon 详解:Hessian 剪枝为什么有效?
算法·机器学习·剪枝
Fer_David2 小时前
解决Windows无法在微软商店安装CodeX问题
windows
硕风和炜2 小时前
【LeetCode: 1301. 最大得分的路径数目 + DP】
java·算法·leetcode·动态规划·dp·记忆化搜索