1005. K 次取反后最大化的数组和
1. first idea
class Solution:
def largestSumAfterKNegations(self, nums: List[int], k: int) -> int:
# 1. find the negative elements with the largest abs value.
# 2. Top(k) of these elements.
all_pos_list = []
nums.sort() # low -> high 这样绝对值最大的负数将率先取反,较小的负数如果没有被反转就留下。
for num in nums:
if (k > 0) and (num < 0):
all_pos_list.append(-num)
k -= 1
else:
all_pos_list.append(num)
all_pos_list.sort() # low -> high 反转后的顺序需要更新顺序,更新后如果k还有剩余,则对最小的值进行反转,这样因为多余反转的损失最小。
print(all_pos_list)
max_sum = 0
k %= 2
for pos_num in all_pos_list:
if k != 0:
max_sum -= pos_num
k -= 1
else:
max_sum += pos_num
return max_sum
134. 加油站
1. first idea
我觉得
- 当前一定要有足够的汽油开往下一站。
car + gas[i] > cost[i] - 如果能开往下一站,那么剩的油越多越好。
- 如果有两个起点都满足上述内容,那么遍历即可。
每个加油站的剩余量rest[i]为gas[i] - cost[i]。
2. doc reading
i从0开始累加rest[i],和记为curSum,一旦curSum小于零,说明[0, i]区间都不能作为起始位置,因为这个区间选择任何一个位置作为起点,到i这里都会断油,
那么起始位置从i+1算起,再从0计算curSum。
如果 curSum<0 说明 区间和1 + 区间和2 < 0, 那么 假设从上图中的位置开始计数curSum不会小于0的话,就是 区间和2>0。
区间和1 + 区间和2 < 0 同时 区间和2>0,只能说明区间和1 < 0, 那么就会从假设的箭头初就开始从新选择其实位置了。
那么局部最优:当前累加rest[i]的和curSum一旦小于0,起始位置至少要是i+1,因为从i之前开始一定不行。全局最优:找到可以跑一圈的起始位置。
class Solution:
def canCompleteCircuit(self, gas: List[int], cost: List[int]) -> int:
if sum(gas) < sum(cost):
return -1
else:
start_idx = 0
while start_idx < len(gas): # 不停寻找起点
idx = start_idx
retain = 0
end_idx = (start_idx + len(gas) - 1) % len(gas) # 计算对应的终点
while idx != end_idx: # 在起点到终点之间的油的变动。
retain = retain + gas[idx] - cost[idx]
if retain < 0:
# 说明当前区间[start_idx, idx]之间不可能存在起点。
break
else:
idx = (idx + 1) % len(gas)
if idx == end_idx:
# 顺利到达终点。
break
else:
start_idx = idx + 1
return start_idx
135. 分发糖果
1. first idea
- 先算个糖果。
- 找到评分最低的那个孩子。
- 如果左侧的孩子比当前孩子评分高,那么就+1.
- 如果左孩子比当前孩子评分低,那么就不动.
2. doc reading
- 初始数组每个单元都为.
- 先从左往右,如果, 那么
- 再从右往左,如果, 那么.
class Solution:
def candy(self, ratings: List[int]) -> int:
candy_list = [1] * len(ratings)
# 从左往右。
for idx in range(1, len(ratings)):
if ratings[idx] > ratings[idx - 1]:
candy_list[idx] = candy_list[idx - 1] + 1
for idx in range(len(ratings) - 2, -1, -1):
if ratings[idx] > ratings[idx + 1]:
candy_list[idx] = max(candy_list[idx], candy_list[idx + 1] + 1)
return sum(candy_list)