代码随想录算法训练营第三十四天| LeetCode1005.K次取反后最大化的数组和、LeetCode134. 加油站、LeetCode135. 分发糖果

文章介绍了使用贪心策略解决三个问题:1005题中通过K次取反最大化数组和,134题中判断是否能完成加油站循环,以及135题中如何公平分发糖果。每个问题都强调了如何根据问题特点进行贪心决策,以求得最优解。
摘要由CSDN通过智能技术生成

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

题目描述: 1005.K次取反后最大化的数组和.

解法

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

贪心的思路应该是在:绝对值越大,那么就要让它是正值,每一个绝对值大的都是正值就好了。
注意这里如何按照绝对值大小排序:nums.sort(key=lambda x:abs(x),reverse=True)
最后还有个技巧,就是如果剩余的k余2得1,那就要把绝对值最小的那个进行反转变为负数。

134. 加油站

题目描述: 134. 加油站.

解法

贪心
class Solution(object):
    def canCompleteCircuit(self, gas, cost):
        need_last = 0
        cur_last = 0
        start = 0
        for i in range(len(gas)):
            cur_last += gas[i] - cost[i]
            if cur_last < 0:
                start = i + 1
                need_last = need_last - cur_last
                cur_last = 0
        if cur_last - need_last < 0:
            return -1
        return start

这个问题并不是将问题最小化,而算是阶段化,不能单个加油站去看,而是这个环状路程中的一段一段去看,如果某一段路程中油耗尽了,那么这一段的任何一个点都不能当作起点,如果我想找到整个路程中的起点,就要遍历这个路程中的每一段,如果这一段欠油,就累计欠的油量,并且将起点设为这一段的下一段的开头,最后遍历完每一段,如果能把拖欠的油全都补完,那么起点就可以设定为最后设为start的那个点,否则就是无法满足跑完一圈的条件。

135. 分发糖果

题目描述: 135. 分发糖果.

解法

贪心
class Solution(object):
    def candy(self, ratings):
        candys = [1] * len(ratings)
        for i in range(1,len(ratings)):
            if ratings[i] > ratings[i-1]:
                candys[i] = candys[i-1] + 1
        for i in range(len(ratings)-2,-1,-1):
            if ratings[i] > ratings[i+1]:
                candys[i] = max(candys[i+1] + 1,candys[i])
        return sum(candys)                

贪心的基本思路就是,局部:一个数的左边满足要求,右边满足要求。全局:所有数都满足左右要求,把局部扩大到整体就好了
那么就需要遍历两次,一次是通过左边的元素确定当前的元素,另一次是通过右边的元素确定当前的元素。
可以把所有内容都初始化成1,因为每个人至少有一个,第一遍遍历是考虑左边的元素,那么就是从index为1的位置开始,一直到末尾,第二遍考虑右边的元素,但是要记得,如果比右边的元素大,那就比他多一个,或者是当前的元素大小不变,选其中大的值就好。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值