题目描述:
给你一个整数数组 arr 和一个目标值 target ,请你返回一个整数 value ,使得将数组中所有大于 value 的值变成 value 后,数组的和最接近 target (最接近表示两者之差的绝对值最小)。
如果有多种使得和最接近 target 的方案,请你返回这些整数中的最小值。
请注意,答案不一定是 arr 中的数字。
今日学习:
好像没学啥,不过我没搞懂leetcode中通不过的例子在vscode中能通过是什么原因,不是时间问题
【2020年6月14日17点24分更新】
原来是递归中忽视了return!!!题解1的代码中
if(count == 0) {
return target - (average * n) > (average + 1) * n - target ? (average + 1) : average
}else{
target = target - sum
findBestValue(arr, target)
}
这部分else中递归的函数需要return findBestValue(arr, target)
题解1:我自己想的,思路在注释中,但是没通过,我觉得没什么问题
var findBestValue = function(arr, target) {
let n = arr.length
let average = Math.floor(target / n)
//先看有没有比average小的,没有就是average或者average + 1
//有的话就先算出比average小的那些数的和再更新average
//都比average小的话就返回数组中的最大值
arr.sort((a, b) => a - b)
if(arr[n - 1] < average) {
return arr[n - 1]
}else {
let count = sum = i = 0
while(arr[i] < average && i < n) {
count++
sum += arr[i]
i++
}
arr.splice(0, count)
if(count == 0) {
return target - (average * n) > (average + 1) * n - target ? (average + 1) : average
}else{
target = target - sum
findBestValue(arr, target)
}
}
};
题解2:二分法
//二分法,屈服了。。。
var findBestValue = function(arr, target) {
let sorted = arr.sort((x,y)=>x-y);
let sums_cur = sorted[0];
let sums_pre = -1;
let value = Math.round(target / sorted.length);
value = Math.min(value, sorted[0]);
for (let i = 1; i < sorted.length; i ++){
sums_pre = sums_cur;
sums_cur = sums_pre + sorted[i];
let new_value = Math.round((target - sums_pre) / (sorted.length - i) - 0.000001);
new_value = Math.min(new_value, sorted[i]);
if (sorted[i-1] > new_value){
break;
}
value = new_value;
}
return value;
};