1005. K 次取反后最大化的数组和
思路:每一次取反最小值即可!贪心的思路就是先排序,反转负数的值,后在贪心反转最小值
class Solution:
def largestSumAfterKNegations(self, nums: List[int], k: int) -> int:
count = 0
while count < k:
# 获取最小值
index = nums.index(min(nums))
nums[index] = - nums[index]
# 其实可以考虑k-- 减少空间开销
count += 1
temp = sum(nums)
return temp
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 nums[i] < 0 and k > 0:
nums[i] = -nums[i]
k -= 1
# 为什么使用% ? 因为偶数的哇,每一次变负数在变为正数相当于没有变化
if k % 2 == 1:
nums[-1] = - nums[-1]
return sum(nums)
134. 加油站
思路:贪心思路就是遇到了加油不足以到达下一个点,就直接从下一个点开始,一轮下来判断总耗油量抵消大于0即可!
贪心算法(方法二)
可以换一个思路,首先如果总油量减去总消耗大于等于零那么一定可以跑完一圈,说明 各个站点的加油站 剩油量rest[i]相加一定是大于等于零的。
每个加油站的剩余量rest[i]为gas[i] - cost[i]。
i从0开始累加rest[i],和记为curSum,一旦curSum小于零,说明[0, i]区间都不能作为起始位置,因为这个区间选择任何一个位置作为起点,到i这里都会断油,那么起始位置从i+1算起,再从0计算curSum。
如图:
那么为什么一旦[0,i] 区间和为负数,起始位置就可以是i+1呢,i+1后面就不会出现更大的负数?
如果出现更大的负数,就是更新i,那么起始位置又变成新的i+1了。
那有没有可能 [0,i] 区间 选某一个作为起点,累加到 i这里 curSum是不会小于零呢? 如图:
那么局部最优:当前累加rest[i]的和curSum一旦小于0,起始位置至少要是i+1,因为从i之前开始一定不行。全局最优:找到可以跑一圈的起始位置。
class Solution:
def canCompleteCircuit(self, gas: List[int], cost: List[int]) -> int:
cur_gas = 0
total_gas = 0
start = 0
for i in range(len(gas)):
# 当前油量是否足以达到下个站
cur_gas += gas[i] - cost[i]
total_gas += gas[i] - cost[i]
if cur_gas < 0:
cur_gas = 0
start = i + 1
if total_gas >=0:
return start
return -1
def canCompleteCircuit1(self, gas: List[int], cost: List[int]) -> int:
# gas是汽油 cost是花费 使用暴力解决
for i in range(len(gas)):
sum_ = gas[i] - cost[i]
# 标志位
mm = len(gas)
index = (i + 1) % mm
# 两个条件
while sum_ > 0 and index != i:
sum_ += gas[index] - cost[index]
# index += 1 如果这样的哇,上述第二条就没有存在的意义了
index = (index + 1) % mm
if sum_ >= 0 and index == i:
return i
return -1
406. 根据身高重建队列
思路:贪心的思路:拆分一组的维度进行排序,比较!确定升高排序后,后定身高从高到低看齐!!!关键点不能两个维度一起考虑,否则会思考不出来的!
注意key的二维数组排序的一些使用技巧:
x[0]
:表示列表中每个元素x
的第一个元素。在这个场景中,people
列表中的每个元素都是一个二元组(或列表),而x[0]
表示每个二元组的第一个元素。-x[0]
:表示对x[0]
的相反数进行比较,即按照第一个元素的逆序进行排序。这意味着具有更大第一个元素的元素将在排序后出现在列表的前面。x[1]
:表示每个二元组的第二个元素。
class Solution:
def reconstructQueue(self, people: List[List[int]]) -> List[List[int]]:
# 像这种多维度的,拆分维度!确定按身高排序先,后定身高大于或等于前面的人
# 身高按高到底这样好排序
people.sort(key=lambda x: (-x[0],x[1]))
que = []
# 比较每个第二维大小,看前面的有没有比起大,从而确定位置插入
for people_ in people:
que.insert(people_[1],people_)
return que