#算法记录 | Day33 贪心算法

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

class Solution:
    def largestSumAfterKNegations(self, A: List[int], K: int) -> int:
        A = sorted(A, key=abs, reverse=True) # 将A按绝对值从大到小排列
        for i in range(len(A)):
            if K > 0 and A[i] < 0:
                A[i] *= -1
                K -= 1
        if K > 0:
            A[-1] *= (-1)**K #取A最后一个数只需要写-1
        return sum(A)

134. 加油站

贪心算法

  • 如果加油站提供的油总和大于等于消耗的汽油量,则必定可以绕环路行驶一周
  • 假设先不考虑油量为负的情况,我们从「第 0 个加油站」出发,环行一周。记录下汽油量 gas[i] 和 cost[i] 差值总和 sum_diff,同时记录下油箱剩余油量的最小值 min_sum。
  • 如果差值总和 sum_diff < 0,则无论如何都不能环行一周。油不够啊,亲!!
  • 如果 min_sum ≥ 0,则行驶过程中油箱始终有油,则可以从 0 个加油站出发环行一周。
  • 如果 min_sum < 0,则说明行驶过程中油箱油不够了,那么考虑更换开始的起点。
    • 从右至左遍历,计算汽油量 gas[i] 和 cost[i] 差值,看哪个加油站能将 min_sum 填平。如果最终达到 min_sum ≥ 0,则说明从该点开始出发,油箱中的油始终不为空,则返回该点下标。
    • 如果找不到最返回 -1
class Solution:
    def canCompleteCircuit(self, gas: List[int], cost: List[int]) -> int:
        sum_diff, min_sum = 0, float('inf')
        for i in range(len(gas)):
            sum_diff += gas[i] - cost[i]
            min_sum = min(min_sum, sum_diff)

        if sum_diff < 0:
            return -1

        if min_sum >= 0:
            return 0

        for i in range(len(gas)-1, -1, -1):
            min_sum += gas[i] - cost[i]
            if min_sum >= 0:
                return i
        return -1

135. 分发糖果

思路:

这道题目一定是要确定一边之后,再确定另一边,例如比较每一个孩子的左边,然后再比较右边,如果两边一起考虑一定会顾此失彼

先确定右边评分大于左边的情况(也就是从前向后遍历)

#算法记录 | Day33 贪心算法_第1张图片

再确定左孩子大于右孩子的情况(从后向前遍历),确定左孩子大于右孩子的情况一定要从后向前遍历!

#算法记录 | Day33 贪心算法_第2张图片

class Solution:
    def candy(self, ratings: List[int]) -> int:
        size = len(ratings)
        sweets = [1 for _ in range(size)]

        for i in range(1, size):
            if ratings[i] > ratings[i - 1]:
                sweets[i] = sweets[i - 1] + 1

        for i in range(size - 2, -1, -1):
            if ratings[i] > ratings[i + 1]:
                sweets[i] = max(sweets[i], sweets[i + 1] + 1)

        res = sum(sweets)
        return res

你可能感兴趣的:(leetcode,算法,贪心算法,leetcode)