1
题目描述
给定一个整数数组 arr 和一个目标值 target ,返回一个整数 value ,使得将数组中所有大于 value 的值变成 value 后,数组的和最接近 target (最接近表示两者之差的绝对值最小)如果有多种使得和最接近 target 的方案,请你返回这些整数中的最小值。如输入arr = [4,9,3], target = 10,输出3,输入arr=[60864,25176,27249,21296,20204],target=56803,输出11361。
2
题解
思路:前缀和,单调性
本题首先要对题目有深入的理解。对于arr[i],数组和S=sum(arr[0:i]+arr[i]*(len(arr)-i)),因此当对arr进行排序后,发现S是关于arr的单调函数,如下图。
(图片来自网络)
因此当出现S>=target时,意味着目标值在(arr[i-1],arr[i]]之间。也就是说在(arr[i-1],arr[i]]之间存在一个数x,使得sum(arr[0:i]+x*(len(arr)-i))=target。此时求出的x可能是小数,因为要求满足条件的最小整数,所以根据小数具体值判断上取整还是下取整即可(类似四舍五入,但当小数部分是0.5时要下取整。找例子具体计算一下就可以理解)。如果S始终小于target,则根据题目要求返回arr中的最大值。
class Solution:
def findBestValue(self, arr: List[int], target: int) -> int:
arr.sort()
pre = 0
for i in range(0,len(arr)):
if pre+arr[i]*(len(arr)-i)>=target:
x = (target-pre)/(len(arr)-i)
if x%1>0.5: return ceil(x)
else : return floor(x)
pre += arr[i]
return arr[-1]