Given an integer array arr and a target value target, return the integer
value such that when we change all the integers larger than value in the given array to be equal to value, the sum of the array gets as close as possible (in absolute difference) to target.
In case of a tie, return the minimum such integer.
Notice that the answer is not neccesarilly a number from arr.
Sort the array. Use binary search to find the value v such that replacing all elements > v with v makes the sum closest to target. For each candidate v, compute the mutated sum and track the minimum difference.
#include<vector>#include<algorithm>usingnamespace std;
classSolution {
public:int findBestValue(vector<int>& arr, int target) {
sort(arr.begin(), arr.end());
int n = arr.size();
vector<int> prefix(n+1);
for (int i =0; i < n; ++i) prefix[i+1] = prefix[i] + arr[i];
int l =0, r = arr[n-1], res =0, diff = INT_MAX;
while (l <= r) {
int m = l + (r-l)/2;
int idx = lower_bound(arr.begin(), arr.end(), m) - arr.begin();
int s = prefix[idx] + (n-idx)*m;
if (abs(s - target) < diff || (abs(s - target) == diff && m < res)) {
res = m; diff = abs(s - target);
}
if (s < target) l = m+1;
else r = m-1;
}
return res;
}
};
import java.util.*;
classSolution {
publicintfindBestValue(int[] arr, int target) {
Arrays.sort(arr);
int n = arr.length;
int[] prefix =newint[n+1];
for (int i = 0; i < n; ++i) prefix[i+1]= prefix[i]+ arr[i];
int l = 0, r = arr[n-1], res = 0, diff = Integer.MAX_VALUE;
while (l <= r) {
int m = l + (r-l)/2;
int idx = Arrays.binarySearch(arr, m);
if (idx < 0) idx =-idx-1;
int s = prefix[idx]+ (n-idx)*m;
if (Math.abs(s - target) < diff || (Math.abs(s - target) == diff && m < res)) {
res = m; diff = Math.abs(s - target);
}
if (s < target) l = m+1;
else r = m-1;
}
return res;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
classSolution {
funfindBestValue(arr: IntArray, target: Int): Int {
arr.sort()
val n = arr.size
val prefix = IntArray(n+1)
for (i in0 until n) prefix[i+1] = prefix[i] + arr[i]
var l = 0; var r = arr[n-1]; var res = 0; var diff = Int.MAX_VALUE
while (l <= r) {
val m = l + (r-l)/2val idx = arr.binarySearch(m).let { if (it < 0) -it-1elseit }
val s = prefix[idx] + (n-idx)*m
if (kotlin.math.abs(s - target) < diff || (kotlin.math.abs(s - target) == diff && m < res)) {
res = m; diff = kotlin.math.abs(s - target)
}
if (s < target) l = m+1else r = m-1 }
return res
}
}
from bisect import bisect_left
classSolution:
deffindBestValue(self, arr: list[int], target: int) -> int:
arr.sort()
n = len(arr)
prefix = [0]*(n+1)
for i in range(n):
prefix[i+1] = prefix[i] + arr[i]
l, r =0, arr[-1]
res, diff =0, float('inf')
while l <= r:
m = (l + r) //2 idx = bisect_left(arr, m)
s = prefix[idx] + (n-idx)*m
if abs(s - target) < diff or (abs(s - target) == diff and m < res):
res, diff = m, abs(s - target)
if s < target:
l = m +1else:
r = m -1return res
impl Solution {
pubfnfind_best_value(mut arr: Vec<i32>, target: i32) -> i32 {
arr.sort();
let n = arr.len();
letmut prefix =vec![0; n+1];
for i in0..n { prefix[i+1] = prefix[i] + arr[i]; }
let (mut l, mut r) = (0, arr[n-1]);
let (mut res, mut diff) = (0, i32::MAX);
while l <= r {
let m = l + (r-l)/2;
let idx = arr.binary_search(&m).unwrap_or_else(|x| x);
let s = prefix[idx] + (n-idx) asi32* m;
if (s - target).abs() < diff || ((s - target).abs() == diff && m < res) {
res = m; diff = (s - target).abs();
}
if s < target { l = m+1; } else { r = m-1; }
}
res
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
functionfindBestValue(arr: number[], target: number):number {
arr.sort((a, b) =>a-b);
constn=arr.length;
constprefix=new Array(n+1).fill(0);
for (leti=0; i<n; ++i) prefix[i+1] =prefix[i] +arr[i];
letl=0, r=arr[n-1], res=0, diff=Infinity;
while (l<=r) {
constm= Math.floor((l+r) /2);
letidx=arr.findIndex(x=>x>=m);
if (idx===-1) idx=n;
consts=prefix[idx] + (n-idx)*m;
if (Math.abs(s-target) <diff|| (Math.abs(s-target) ===diff&&m<res)) {
res=m; diff= Math.abs(s-target);
}
if (s<target) l=m+1;
elser=m-1;
}
returnres;
}