题目 1005.K次取反后最大化的数组和
问题描述
给定一个整数数组 A,我们只能用以下方法修改该数组:我们选择某个索引 i 并将 A[i] 替换为 -A[i],然后总共重复这个过程 K 次。(我们可以多次选择同一个索引 i。)
以这种方式修改数组后,返回数组可能的最大和。
示例 1:
输入:A = [4,2,3], K = 1
输出:5
解释:选择索引 (1,) ,然后 A 变为 [4,-2,3]。
示例 2:
输入:A = [3,-1,0,2], K = 3
输出:6
解释:选择索引 (1, 2, 2) ,然后 A 变为 [3,1,0,2]。
解题思路
- 优先变负数,优先变负数里面负得最多的(按绝对值最大的数排序)
- k用完了,而且所有的都是正数,就优先变小的正数(用剩余的k次反复遍)。
- 如果k为奇数,那么最小那个正数变k次就是负,反之则正。
代码问题
-求和sum(nums)
-改变list里面的数值,for循环要用index,这样才能改。
代码
class Solution:
def largestSumAfterKNegations(self, nums: List[int], k: int) -> int:
#排序数组
nums.sort()
#优先变化负得最大的
for i in range(len(nums)):
if nums[i]<0 and k>0:
nums[i]*=(-1)
k-=1
#截止目前上面已经全部是正数了
if k%2==1:
#谁是最小的正数值
min_num=min(nums)
#这个数的index是多少
min_num_index = nums.index(min_num)
#根据这个数的index把它变成负数
nums[min_num_index]*=-1
return sum(nums)
复杂度分析
题目 135. 分发糖果
问题描述
老师想给孩子们分发糖果,有 N 个孩子站成了一条直线,老师会根据每个孩子的表现,预先给他们评分。
你需要按照以下要求,帮助老师给这些孩子分发糖果:
每个孩子至少分配到 1 个糖果。
相邻的孩子中,评分高的孩子必须获得更多的糖果。
那么这样下来,老师至少需要准备多少颗糖果呢?
示例 1:
输入: [1,0,2]
输出: 5
解释: 你可以分别给这三个孩子分发 2、1、2 颗糖果。
示例 2:
输入: [1,2,2]
输出: 4
解释: 你可以分别给这三个孩子分发 1、2、1 颗糖果。第三个孩子只得到 1 颗糖果,这已满足上述两个条件。
解题思路
两边分别考虑,两个for循环
-
右边孩子比左边高(从前向后遍历num1)
-
- 大的加一(在小孩子数值的情况下+1)
-
- 小的就是1
-
左边孩子比右边高(从后向前遍历num2)
-
- 大的加一(在小孩子数值的情况下+1)
-
- 小的就是上面那种情况计算的值
-
汇总
-
- 对应糖果为,num2[i]=max(第二种情况右孩子加1和第一种情况左孩子加一)
- 对应糖果为,num2[i]=max(第二种情况右孩子加1和第一种情况左孩子加一)
代码问题
- 注意是用原数组比较,然后对新数组做处理
代码
class Solution:
def candy(self, ratings: List[int]) -> int:
#全员初始化为1
nums=[1]*len(ratings)
#第一个forloop,从左向右
for i in range(len(ratings)-1):
if ratings[i + 1] > ratings[i]:
nums[i + 1] = nums[i] + 1
#第二个forloop,从右向左
for i in range(len(ratings) - 1, 0, -1):
if ratings[i - 1] > ratings[i]:
nums[i - 1] = max(nums[i - 1], nums[i] + 1)
return sum(nums)
复杂度分析
题目 134. 加油站
问题描述
在一条环路上有 N 个加油站,其中第 i 个加油站有汽油 gas[i] 升。
你有一辆油箱容量无限的的汽车,从第 i 个加油站开往第 i+1 个加油站需要消耗汽油 cost[i] 升。你从其中的一个加油站出发,开始时油箱为空。
如果你可以绕环路行驶一周,则返回出发时加油站的编号,否则返回 -1。
说明:
如果题目有解,该答案即为唯一答案。
输入数组均为非空数组,且长度相同。
输入数组中的元素均为非负数。
示例 1: 输入:
gas = [1,2,3,4,5]
cost = [3,4,5,1,2]
输出: 3 解释:
从 3 号加油站(索引为 3 处)出发,可获得 4 升汽油。此时油箱有 = 0 + 4 = 4 升汽油
开往 4 号加油站,此时油箱有 4 - 1 + 5 = 8 升汽油
开往 0 号加油站,此时油箱有 8 - 2 + 1 = 7 升汽油
开往 1 号加油站,此时油箱有 7 - 3 + 2 = 6 升汽油
开往 2 号加油站,此时油箱有 6 - 4 + 3 = 5 升汽油
开往 3 号加油站,你需要消耗 5 升汽油,正好足够你返回到 3 号加油站。
因此,3 可为起始索引。
解题思路
- 开一圈刚好剩余的油为0,重点在选择开始的地方。
- 暴力解法,模拟循环,复杂度为n方。
- 如果从A点出发无法到达B点(A在B之前),那么任何在A和B之间的点C都不能从C点出发到达B点。这是因为A点油量是足够的,但在到达B点之前油箱为空了,所以C点的起始油量会更少。
- 如果所有加油站的总油量大于或等于总消耗,那么一定可以环绕一圈。
- current_sum: 表示从起始点到当前点的净油量(即加油站提供的油量减去到下一个加油站的消耗)。
- total_sum: 表示所有加油站的总净油量。
- start: 表示我们正在考虑的起始点。
代码
class Solution:
def canCompleteCircuit(self, gas: List[int], cost: List[int]) -> int:
#中心思想:如果a在b之前,a点到不了b点,那么ab的终点c也到不了b点
#实时油耗
current_sum=0
#总体油耗
total_sum=0
#刚好可以循环一周的index
start=0
for i in range(len(gas)):
current_sum+=(gas[i]-cost[i])
total_sum+=(gas[i]-cost[i])
if current_sum<0:
#更新实时和为0,start
current_sum=0
start=i+1
if total_sum<0:
return -1
return start
复杂度分析
题目
问题描述
解题思路
代码
复杂度分析
题目 104
问题描述
解题思路
代码