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

Leetcode - 1005

我的思路,首先对列表进行排序,这样绝对值大的负数都会被排在前面,此时我们进行遍历,遇到负数,直接取反,然后k-1,遍历到末尾或者k=0时结束。

结束后若k=0 则返回结果

若不为0,我们需要将k用在绝对值最小的正数上(此时负数都取反了),所以再进行一次排序,

此时分为两种情况,若k为偶数,则k次翻转过后值不会变,直接返回当前的和。

若k为奇数,则会取反,此时的和减去最小元素的值再加上最小元素值的相反数即可

def largestSumAfterKNegations(self, nums: List[int], k: int) -> int:
        nums.sort()
        for i in range(len(nums)):
            if nums[i] < 0:
                nums[i] = -1 * nums[i]
                k -= 1
            else:
                break

            if k == 0:
                return sum(nums)

        if k == 0:
            return sum(nums)

        nums.sort()
        if k % 2 == 0:
            return sum(nums)
        else:
            return sum(nums) - nums[0] + -1 * nums[0]

Leetcode - 134

这题python用暴力法是没法解决的,我做了两种剪枝都不行,在起始点位置的选择上剪枝,和对整体上判断gas和 与 cost和的关系。都不行

果断选择用卡哥的方法二,方法二里,我进行一点小调整: 我首先是保证gas只和要>=cost只和,这样才能继续,保证有一个点能满足结果。否则return False。

用start来记录起点,用一个变量currSum用来记录当前gas[i]和cost[i]的差值的累积值,若这个值小于0,则代表0~i区间不可能存在合理的起点,至少是下一个位置才可能是合理的,所以currSum<0时,start = i+1,且此时currSum需要重置为0

比如: gas = [1,2,3,4,5], cost = [3,4,5,1,2]

index = 0~2时, gas[i]-cost[i]均为-2,index=3是合理的值,若此时currSum不重置,则到index = 3处currSum仍然为负数,误将index=3也判断为不合理起点了

另外一个问题是,找到一个合理起点后,后面会不会有更大的负数,且这个负数绝对值大于当前的正数差值,不可能的,因为前面我们已经判断过了,gas总和是大于cost总和的,前面有多少负数,后面就会有多少正数的。况且找到一个暂时的起点后,currSum会继续累加,<0后仍然会置0,循环往复,直到碰到合适的值为止。

def canCompleteCircuit(self, gas: List[int], cost: List[int]) -> int:
        start = 0
        curSum = 0
        totalSum = 0
        for i in range(len(gas)):
            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

Leetcode - 135

这题看着不难,但是很难想到,这题我们不能同时兼顾两边,只能先处理完一边后再处理另一边,先初始化一个结果数组,长度和ratings一致,每个位置的元素均为1,然后开始遍历rating,此时我们先处理每个孩子右边的孩子,若右边的孩子比左边孩子得分高,设左边孩子苹果数为res[i],则此时将res[i+1]赋值为res[i]+1,注意此时一定不能直接对res[i+1]+=1, 因为他们初始值都为1,此时res[i+1]+=1后变为2,但是ratings[i+2] > ratings[i+1]时,仍然对res[i+2]+=1,则此时res[i+1],res[i+2]均为2,不符合题目要求

右边处理完后,再从数组末尾开始遍历,判断左边的孩子,若左边孩子对应的rating元素更大,则先判断一下res[i-1] 是否大于res[i]若已经大于了,则我们不必再操作,反之,res[i-1] = res[i] +1.

最后返回res的和即可。

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

       
        for i in range(len(ratings)-1,0,-1):
            if ratings[i-1] > ratings[i]:
                if not res[i-1] > res[i]:
                    res[i-1]  = res[i] +1

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值