思路比较简单,把所有的负数绝对值大的全部取反之后再在新的数组里把绝对值最小的重复取反即可。
class Solution(object):
def largestSumAfterKNegations(self, nums, k):
"""
:type nums: List[int]
:type k: int
:rtype: int
"""
# 按照绝对值的大小从大到小排序(方便后面直接取出绝对值最小的值)
nums.sort(key = lambda x: abs(x), reverse = True)
for i in range(len(nums)):
if nums[i] < 0 and k > 0:
nums[i] = -nums[i]
k -= 1
if k % 2:
nums[-1] = -nums[-1]
return sum(nums)
本题适合从差值入手,也就是引入一个gas-cost的变量来标记经过每一个车站的剩余油量。
分别记录当前的总剩余量和每次走过后的剩余量:
1、总剩余量小于0,说明无论如何都无法走完全程;
2、当前剩余量小于0,说明之前一个起始点位置不对,需要从i+1开始当作起始点;
3、由于答案是唯一的,所以最后满足条件的起始位置就是返回的结果。
由于1、2步可以在同一个遍历全部数组的循环中实现,所以只要一个for从开头遍历到结尾即可。?
class Solution(object):
def canCompleteCircuit(self, gas, cost):
"""
:type gas: List[int]
:type cost: List[int]
:rtype: int
"""
start = 0
cur_sum = 0
ttl_sum = 0
for i in range(len(gas)):
ttl_sum += gas[i] - cost[i]
cur_sum += gas[i] - cost[i]
if cur_sum < 0:
start = i + 1
cur_sum = 0
if ttl_sum < 0:
return -1
return start
本题的思路是分两次谈心,两次遍历的局部最优就是全局最优。
首先,初始化全部的糖果数量,保证每个人至少都能分到一个糖果。
第一遍,从左往右,如果右边的比左边评分高,那么右边的比左边多一个糖果;
第二遍,从右往左,如果左边的评分比右边的高,那么此时需要比较“左边经过第一遍之后的糖果”和“右边糖果数量+1”谁更大,取较大值即可。
class Solution(object):
def candy(self, ratings):
"""
:type ratings: List[int]
:rtype: 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]) # 注意,如果是本来分发的糖果数量比右边的+1还要大,那就不需要再给新的糖果了(保证最少)
return sum(candy_list)
OMG断卡两周再次继续!!第33天完结!!