1005.K次取反后最大化的数组和
两次贪心
- 将负数反转,按照绝对值从大到小的顺序
- 如果还有剩余反转次数,则将绝对值最小的值反复反转
做题步骤
- 按照绝对值从大到小排序
- 从大到小遍历数组,遇到负数则反转,k-1
- 如果还有剩余反转次数,则将绝对值最小的值反复反转
- 求和
class Solution:
def largestSumAfterKNegations(self, nums: List[int], k: int) -> int:
nums.sort(key=lambda x: abs(x), reverse=True)
for i in range(len(nums)):
if k <= 0:
break
if nums[i] < 0:
nums[i] *= -1
k -= 1
if k % 2 == 1:
nums[-1] *= -1
return sum(nums)
134. 加油站
从i开始累加剩余油量curSum,一但curSum<0,则调到当前位置的下一个,因为从i开始到当前都不可能作为起始站了。
还有一个要从全局进行考虑,总油量必须要大于等于总消耗,因为这样才能在判断起始站后,后续的油量是大于等于消耗的,才能满足条件
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:
start = i + 1
curSum = 0
if totalSum < 0:
return -1
return start
135. 分发糖果
- 先从左往右遍历,确定右边孩子比左边孩子评分高的可以满足
- 再从右往左遍历,确定左边孩子比右边孩子评分高的可以满足
class Solution:
def candy(self, ratings: List[int]) -> int:
candy_list = [1] * len(ratings)
for i in range(1, len(ratings)):
if ratings[i] > ratings[i-1]:
candy_list[i] = candy_list[i-1] + 1
for i in range(len(ratings)-2, -1, -1):
if ratings[i] > ratings[i+1]:
candy_list[i] = max(candy_list[i+1]+1, candy_list[i])
return sum(candy_list)