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

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

本题简单一些,估计大家不用想着贪心 ,用自己直觉也会有思路。 

代码随想录

思路

找到最小值,给他加上负号,循环k次,再求total

class Solution:
    def largestSumAfterKNegations(self, nums: List[int], k: int) -> int:
        while k>0:
            nums.sort()
            nums[0]*=-1
            k-=1
            total=0
        for i in range(len(nums)):
            total+=nums[i]
        return total
class Solution:
    def largestSumAfterKNegations(self, A: List[int], K: int) -> int:
        A.sort(key=lambda x: abs(x), reverse=True)  # 第一步:按照绝对值降序排序数组A

        for i in range(len(A)):  # 第二步:执行K次取反操作
            if A[i] < 0 and K > 0:
                A[i] *= -1
                K -= 1

        if K % 2 == 1:  # 第三步:如果K还有剩余次数,将绝对值最小的元素取反
            A[-1] *= -1

        result = sum(A)  # 第四步:计算数组A的元素和
        return result

总结

我的方法除了时间要的长一些,也能算对。答案的思路我之前是有的,只是不知道怎么求绝对值,还有可以用sum()函数求总和,对python的内置函数还不熟悉。abs()函数是求绝对值的。

134. 加油站 

本题有点难度,不太好想,推荐大家熟悉一下方法二 

代码随想录

思路

至少在几道贪心的题之后,知道这道题要算差值,再进行判断

class Solution:
    def canCompleteCircuit(self, gas: List[int], cost: List[int]) -> int:
        for i in range(len(cost)):
            rest = gas[i] - cost[i]  # 记录剩余油量
            index = (i + 1) % len(cost)  # 下一个加油站的索引

            while rest > 0 and index != i:  # 模拟以i为起点行驶一圈(如果有rest==0,那么答案就不唯一了)
                rest += gas[index] - cost[index]  # 更新剩余油量
                index = (index + 1) % len(cost)  # 更新下一个加油站的索引

            if rest >= 0 and index == i:  # 如果以i为起点跑一圈,剩余油量>=0,并且回到起始位置
                return i  # 返回起始位置i

        return -1  # 所有起始位置都无法环绕一圈,返回-1

答案

class Solution:
    def canCompleteCircuit(self, gas: List[int], cost: List[int]) -> int:
        curSum = 0  # 当前累计的剩余油量
        totalSum = 0  # 总剩余油量
        start = 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  # 起始位置更新为i+1
                curSum = 0  # curSum重新从0开始累计
        
        if totalSum < 0:
            return -1  # 总剩余油量totalSum小于0,说明无法环绕一圈
        return start

总结

本来只要在第一次循环中加入当rest大于0的情况进行遍历,结果我是先循环把rest大于零的下标记录下来再从新进行遍历,这我都不知道为什么我这么蠢。感觉这答案所写的贪心这不就是暴力法吗?为什么可以称为贪心?

 135. 分发糖果 

本题涉及到一个思想,就是想处理好一边再处理另一边,不要两边想着一起兼顾,后面还会有题目用到这个思路 

代码随想录

状态:看了思路未写出来

自己写的

class Solution:
    def candy(self, ratings: List[int]) -> int:
        nums=[1]*len(ratings)
        for i in range(len(ratings)):  #从左向右
            if i>0 and ratings[i]>ratings[i-1]:
                nums[i]=nums[i-1]+1
        total=0
        l=len(ratings)-1
        for i in range(l,-1,-1): #从右向左
            if 0ratings[i+1]:
                nums[i]=nums[i+1]+1
            total+=nums[i]
        return total

答案

class Solution:
    def candy(self, ratings: List[int]) -> int:
        candyVec = [1] * len(ratings)
        
        # 从前向后遍历,处理右侧比左侧评分高的情况
        for i in range(1, len(ratings)):
            if ratings[i] > ratings[i - 1]:
                candyVec[i] = candyVec[i - 1] + 1
        
        # 从后向前遍历,处理左侧比右侧评分高的情况
        for i in range(len(ratings) - 2, -1, -1):
            if ratings[i] > ratings[i + 1]:
                candyVec[i] = max(candyVec[i], candyVec[i + 1] + 1)
        
        # 统计结果
        result = sum(candyVec)
        return result

总结

其实我觉得这思路不容易理解,我应该也是没把思路理解清楚所以写不出来的。

你可能感兴趣的:(算法,leetcode,职场和发展)