day34| 1005+134+135

发布时间 2023-04-21 00:16:04作者: blueCP1999

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

 

题目简述:

给你一个整数数组 nums 和一个整数 k ,按以下方法修改该数组:

选择某个下标 i 并将 nums[i] 替换为 -nums[i] 。
重复这个过程恰好 k 次。可以多次选择同一个下标 i 。

以这种方式修改数组后,返回数组 可能的最大和 。

 

思路:

1. 当数组中负数足够多,我们每一次改变负数的符号

2. 当负数都改完了,k还没等于0,假设k为偶数,选取当前数组中的最小值连着改变两次;假设为奇数,改变一次即可

 

代码如下:

from math import inf
class Solution:
    def largestSumAfterKNegations(self, nums: List[int], k: int) -> int:
        nums.sort()
        m, ans = inf, 0
        for num in nums:
            m = min(m, abs(num))
            if num < 0 and k:
                k -= 1
                ans -= num
            else:
                ans += num
        # 只有一种情况我们需要减去最小的那个,k多余了且是奇数(由于已经加进去了所以要减2倍)
        return ans - 2 * m if k and k % 2 else ans

 

134. 加油站

 

题目简述:

在一条环路上有 n 个加油站,其中第 i 个加油站有汽油 gas[i] 升。

你有一辆油箱容量无限的的汽车,从第 i 个加油站开往第 i+1 个加油站需要消耗汽油 cost[i] 升。你从其中的一个加油站出发,开始时油箱为空。

给定两个整数数组 gas 和 cost ,如果你可以绕环路行驶一周,则返回出发时加油站的编号,否则返回 -1 。如果存在解,则 保证 它是 唯一 的。

 

 

思路:

1. 既然车要能开下去,那必须时时刻刻油量大于等于消耗量

2. 从左至右遍历数组,记录总的油量-消耗量,记录当前站点的油量-消耗量

3. 总的小于0,那必定不行的;某一站点的油量-消耗量小于0,那也不行,假设下一个站点可行,用一个变量标记某一站点油量-消耗量大于等于0的那一时刻。

 

代码如下:

 

class Solution:
    def canCompleteCircuit(self, gas: List[int], cost: List[int]) -> int:
        # total记录可获得的总油量-总油耗, cur记录当前油耗情况, ans记录出发位置
        total, cur, ans = 0, 0, 0
        for i in range(len(gas)):
            total += gas[i] - cost[i]
            cur += gas[i] - cost[i]
            if cur < 0:                     # 油不够开到i站
                cur = 0                     # cur置零,在新位置重新开始计算油耗情况
                ans = i + 1                 # 将起始位置改成i+1
        return ans if total >= 0 else -1    # 如果获得的汽油的量小于总油耗,则无法环
                                            # 行一周返回 -1;反之返回ans
       

 

 

135. 分发糖果

 

题目简述:

n 个孩子站成一排。给你一个整数数组 ratings 表示每个孩子的评分。

你需要按照以下要求,给这些孩子分发糖果:

每个孩子至少分配到 1 个糖果。
相邻两个孩子评分更高的孩子会获得更多的糖果。
请你给每个孩子分发糖果,计算并返回需要准备的 最少糖果数目 。

 

思路:

 左规则:当ratings[i]<ratings[i-1]时,i号学生的糖果数量将比i-1号孩子的糖果数量多

右规则: 当ratings[i]>ratings[i+1]时,i号学生的糖果数量将比i+1号孩子的糖果数量多

 

二次遍历

 

代码如下:

class Solution:
    def candy(self, ratings: List[int]) -> int:
        n = len(ratings)
        left = [0] * n
        for i in range(n):
            if i > 0 and ratings[i] > ratings[i - 1]:
                left[i] = left[i - 1] + 1
            else:
                left[i] = 1
        
        right = ret = 0
        for i in range(n - 1, -1, -1):
            if i < n - 1 and ratings[i] > ratings[i + 1]:
                right += 1
            else:
                right = 1
            ret += max(left[i], right)
        
        return ret