day34|贪心算法3-分发糖果&加油站

1005.K次取反后最大化的数组和

贪心的思路,局部最优 :让绝对值大的负数变为正数,当前数值达到最大,整体最优:整个数组和达到最大。
局部最优可以推出全局最优。
那么如果将负数都转变为正数了,K依然大于0,此时的问题是一个有序正整数序列,如何转变K次正负,让 数组和 达到最大。
那么又是一个贪心:局部最优:只找数值最小的正整数进行反转,当前数值和可以达到最大(例如正整数数组{5, 3, 1},反转1得到-1 比 反转5得到的-5大多了),全局最优:整个数组和 达到最大。

class Solution:
    def largestSumAfterKNegations(self, nums: List[int], k: int) -> int:
        nums = sorted(nums)
        # 优先把所有的负数变成正数
        i = 0
        while k :
            if nums[0] < 0:
                nums[0] = - nums[0]
                nums = sorted(nums)
            elif k % 2 == 0:
                return sum(nums)
            elif k % 2 != 0:
                return sum(nums) - 2*nums[0]
            k -= 1
        return sum(nums)

134. 加油站

在这里插入图片描述

  1. 暴力法: 一次将五个站点作为初始站点,看遍历完所有的节点之后油是否够用。
    转圈的情况利用while循环进行求解。
  2. 贪心算法1:
  3. 贪心算法2: 计算每一步的剩余油量值,累加每一个站点的剩余油量,如果累计的油量小于0的话,这个时候应应该将下一个结点作为开始的坐标。
    最关心的是补充消耗之后是增油还是减油,所以可以利用res数组记录结余的油量,
class Solution:
    def canCompleteCircuit(self, gas: List[int], cost: List[int]) -> int:
        res = [0] * len(gas)
        for i in range(len(gas)):
            res[i] = gas[i] - cost[i]
        # 先做整体的剪枝
        if sum(res) < 0 :
            return -1
        start = 0
        curSum = 0
        cur = 0
        # 再对剩余的各种情况进行求解。
        while cur < len(gas):
            curSum += res[cur]
            if curSum < 0:
                start = cur + 1
                curSum = 0
            cur += 1
        return start
            

135. 分发糖果

本题涉及到一个思想,就是 想处理好一边再处理另一边 ,不要两边想着一起兼顾,后面还会有题目用到这个思路
面临的问题是既要考虑左边的节点,又要考虑右边的节点。

  1. 先只确定右边的小孩比左边的小孩的得分高:从前向后遍历
  2. 左孩子比右孩子得分高:从后向前遍历
    在这里插入图片描述
class Solution:
    def candy(self, ratings: List[int]) -> int:
        result = [1] * len(ratings)
        # 从前往后找
        for i in range(1,len(ratings)):
            if ratings[i] > ratings[i-1]:
                result[i] = result[i-1] + 1
        # 从后往前找
        for i in range(len(ratings)-2,-1,-1):
            if ratings[i+1] < ratings[i]:
                result[i] = max(result[i+1] + 1, result[i])
        return sum(result)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值