青训营: 小L的元素修改问题 | 豆包MarsCode AI刷题

26 阅读2分钟

问题描述

小R拿到了一个数组,她可以进行如下操作:使得一个元素加1,另一个元素减1。她希望最终数组的每个元素大小都在[1,r]的范围内。小R想知道,最少需要多少次操作可以达到目标。 如果无法通过有限次操作使所有元素都落在指定范围内,则返回-1。

测试样例

样例1: 输入:n=21=3,r=[1,21] 输出:-1

样例2: 输入:n=3,1=4,r=6,a=[3,6,5]输出:1

样例3: 输入:n=4,1=2r=8,a=[1,10,2,6]输出:2

题目分析

这道题目难点在于考虑清楚什么情况下是满足题目要求的条件的:即可以使所有元素都落在指定范围内。 最开始考虑小于L大于R的元素,但不要忘记了在[1,r]范围内的元素也可以向左向右移动。 所以要统计4个求和:

这个问题的核心是 调整数组元素,使得它们都满足给定的范围 [1, r],通过两种操作来调整:一个元素加1,另一个元素减1。目标是最少的操作次数,或者判断是否无法通过有限次操作使所有元素满足条件。

首先,统计出所有小于L的元素与L的差值和suml1。同理求出所有大于r的元素与r的差值和sumr1。

当给出的数据能够达到所有元素移动到范围中时,最终的结果就是max(suml1,sumr1)

同时要统计大于L的元素到L的差值和suml2、小于r的元素到r的差值和sumr2。

由于小于r的元素均可以+1;大于L的元素均可以-1。

所以最终满足条件的数据是sumr1 <= suml2 and suml1 <= sumr2: 解释为suml2代表了所有可减一的元素均减一到l的最大范围;sumr2代表了所有可加一元素均加一到r的最大范围。 这样就得到了最终的满足要求的取值范围。

要注意题目并没有说提供的数据是满足r>=l的,所以要添加判断条件

最终的code如下。

image.png

代码解释:

  1. 初始化low_needhigh_need 分别表示需要增加和减少的操作次数。
  2. 遍历数组:对于每个元素,如果它小于下界 l,就需要增加到 l,并累加需要增加的次数;如果它大于上界 r,就需要减少到 r,并累加需要减少的次数。
  3. 判断可行性:如果 low_needhigh_need 不相等,说明无法通过操作调整数组符合条件,返回 -1。如果相等,返回 low_need(或 high_need),即最小操作次数。