Day 33 | 贪心算法03

54 阅读1分钟

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

复杂度比较高的做法,通过每次排序选择当时最小的数取反

def largestSumAfterKNegations(self, nums: List[int], k: int) -> int:
    # nums.sort()
    s = sum(nums)
    for i in range(k):
        nums.sort()
        s -= 2 * nums[0]
        nums[0] = - nums[0]        
        
    return s

更好的方法(待补)

134. 加油站

def canCompleteCircuit(self, gas: List[int], cost: List[int]) -> int:
    # 原思路:
    # 先遍历gas和cost数组 选择gas[i] >= cost[i]的点开始
    # 从这个点往后遍历 用上一点的值 + gas[i] - cost[i] 值小于零时返回

    # 改进思路:
    # 计算从某个点开始的curSum和totalSum 如果cur小于零 跳过 从下一点开始
    start = 0
    cur = 0
    n = len(gas)
    total = 0
    for i in range(n):
        # cur为改变下标后至i的值 注意也是累计量
        cur += gas[i] - cost[i]
        # total为起始位置的值
        total += gas[i] - cost[i]

        if cur < 0:
            cur = 0
            start = i + 1
    if total < 0:
        return -1

    return start

135. 分发糖果

通过试测试用例debug了很多次

注意是通过res数组赋值

从后往前遍历时,需要注意不覆盖第一次赋的值

def candy(self, ratings: List[int]) -> int:
    # 遍历 仅考虑一边的情况
    
    res = [1] *  len(ratings)
    # 先从头往后遍历
    for i in range(1, len(ratings)):
        if ratings[i] > ratings[i-1]:
            res[i] = res[i-1] + 1
    # 再从尾往前
    for j in range(len(ratings)-2,-1,-1):
        if ratings[j] > ratings[j+1] and res[j] <= res[j+1]:
            res[j] = res[j+1] + 1
    # print(res)
    return sum(res)