代码随想录算法训练营第三十四天

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

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

题目链接:K次取反后最大化的数组和
没用贪心,用的分类和递归

非贪心

class Solution:
    def largestSumAfterKNegations(self, nums: List[int], k: int) -> int:
        pos = []
        neg = []
        for i in range(len(nums)):
            if nums[i] < 0 :
                neg.append(nums[i])
            else:
                pos.append(nums[i])

        pos.sort()
        neg.sort()
        
        if neg == []:
            if k % 2 == 0:
                return sum(nums)
            else:
                return sum(nums)-2*pos[0]
        else:
            if len(neg) < k:
                for i in range(len(nums)):
                    if nums[i] < 0:
                        nums[i] = -nums[i]
                return self.largestSumAfterKNegations(nums,(k-len(neg)))
            else:
                for i in range(k):
                    neg[i] = -neg[i]
                return sum(pos)+sum(neg)            

贪心

贪心算法是按照绝对值排序,如果把负数从绝对值大到小改正,知道k次数用完,如果没用完就找绝对值最小的数消耗完。

class Solution(object):
    def largestSumAfterKNegations(self, nums, k):
        """
        :type nums: List[int]
        :type k: int
        :rtype: int
        """
        nums = sorted(nums, key=abs, reverse=True)
        for i in range(len(nums)):
            if k > 0 and nums[i] < 0:
                nums[i] *= -1
                k -= 1
        while k > 0:
            nums[-1] *= -1
            k-=1
        
        return sum(nums)

134. 加油站

题目链接:加油站

暴力解法

不出意外,超时了,错在33 / 39。

class Solution:
    def canCompleteCircuit(self, gas: List[int], cost: List[int]) -> int:
        for i in range(len(gas)):
            #print("i",i)
            j = 0
            st = list(range(i,len(gas))) + list(range(i))
            total = gas[st[j]]
            while j < (len(gas)-1):
                #print("j",j)
                #print(total,cost[st[j]])
                if total<cost[st[j]]:
                    break
                else:
                    total -= cost[st[j]]
                    total += gas[st[j+1]]
                    j+=1
            
            if j == (len(gas)-1) and total >= cost[st[-1]]:
                return i
        return -1

贪心算法

这里的逻辑是,如果一天的剩余油量加起来不是0的话就完全不够跑这一圈。
如果累计剩余变成了负数,那么我们就从curstate的下一个重新开始计数。
这样遍历完的start,要么是真正的答案,要么就是-1。

  • 为什么不在前面,假设现在在j,我觉得在i<j的位置,那么就是说,我觉得i到j之间的sum一定是正的,但是因为现在到start换到j了,就意味着到j的curstate是负的,那么由于到i的curstate加上i到j之间的sum等于到j的curstate,那么到i的curstate一定是负的,所以i其实已经是过start了,现在到j就说明i不行。
  • 为什么不在后面,因为是遍历到底的,一旦不行就换,遍历到最后的一定是最后一个可以的。
class Solution:
    def canCompleteCircuit(self, gas: List[int], cost: List[int]) -> int:
        start = 0
        curSum = 0
        totalSum = 0
        for i in range(len(gas)):
            print(curSum)
            print(totalSum) #这里是判断整个数组能不能行的
            curSum += gas[i] - cost[i]
            totalSum += gas[i] - cost[i]
            if curSum < 0:
                curSum = 0
                start = i + 1
        if totalSum < 0: return -1
        return start

135. 分发糖果

题目链接:分发糖果
隐约想到一点,左边开始给小朋友糖果的情况和右边开始给小朋友糖果的情况分开统计,最后选大的那个加起来就可以。
注意就是假设从左边开始看,如果右边的孩子比有左边,那么左边的孩子还是一颗糖,而不是右边的孩子减一。

class Solution:
    def candy(self, ratings: List[int]) -> int:
        candy1 = [1]*len(ratings)
        candy2 = [1]*len(ratings)
        for i in range(1,len(ratings)):
            if ratings[i] > ratings[i-1]:
                candy1[i] = candy1[i-1]+1

        for i in range(-2,-(len(ratings)+1),-1):
            if ratings[i] > ratings[i+1]:
                candy2[i] = candy2[i+1]+1
        s = 0
        for i in range(len(candy1)):
            s += max(candy1[i], candy2[i])
        return s





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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值