Day 32 贪心算法 part03

Day 32 贪心算法 part03

3道题目
1005. K 次取反后最大化的数组和
134. 加油站
135. 分发糖果

解题理解

1005

看起来是道简单题,但实现完发现有个样例怎么都过不了,仔细看了题干和题解之后才意识到,k是取负的次数,之前想的是直接按从小到大排序,取前k个小于等于0的数取反就能得到最大值,所以有的样例会得到比答案更大的和。
正确思路是,按绝对值大小从大到小排序,让前k个小于0的数取反,如果不够k个,就让最小的数反复取完最后的次数。

class Solution:
    def largestSumAfterKNegations(self, nums: List[int], k: int) -> int:
        nums.sort(key = lambda x: abs(x), reverse = True)
        for i in range(len(nums)):
            if nums[i] < 0 and k > 0:
                k -= 1
                nums[i] *= -1
        if k % 2 == 1:
            nums[-1] *= -1
        return sum(nums)

134

这里的贪心思想有点削峰填谷的意思,首先逐个遍历gas和cost,gas[i] - cost[i]是当天的剩油量,如果遍历完一圈,剩油量还大于0,说明从0开始就可以跑完;其次如果总油量<总消耗,那无论怎样都跑不完;最后当计算遍历两个数组后,剩油量是负数时,从gas后往前遍历,哪一站能填平这个缺口,就是开始的站点,因为只有在能填平负数的那一站开始,才能保证多跑一圈后到该站能把油量补上。

class Solution:
    def canCompleteCircuit(self, gas: List[int], cost: List[int]) -> int:
        rest = 0
        mingas = 10000000
        for i in range(len(gas)):
            rest += gas[i] - cost[i]
            if mingas > rest:
                mingas = rest
        if rest < 0:
            return -1
        if mingas >= 0:
            return 0
        index = len(gas) - 1
        while index > 0:
            mingas += gas[index] - cost[index]
            if mingas >= 0:
                return index
            index -= 1

135

这道题的贪心思想要分两个方向看,这种思路确实再怎么想也想不到,大致就是,先给每个孩子一个糖果,然后先从左到右看,分数更高的多分一个,相等或小于的维持1个不动,然后再从右往左看,分数更高的那个需要跟右边小于他的糖果数+1比,谁大就给分数更高的孩子。

class Solution:
    def candy(self, ratings: List[int]) -> int:
        candynum = [1] * len(ratings)
        for i in range(1, len(ratings)):
            if ratings[i] > ratings[i - 1]:
                candynum[i] = candynum[i - 1] + 1
        i = len(ratings) - 2
        while i >= 0:
            if ratings[i] > ratings[i + 1]:
                candynum[i] = max(candynum[i], candynum[i + 1] + 1)
            i -= 1
        return sum(candynum)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值