题意
传送门 LeeCode 1300. 转变数组后最接近目标值的数组和
题解
三分
随着 v a l u e value value 减小,数组和非严格递减。那么 t a r g e t target target 与数组和的绝对值在 v a l u e value value 附近会出现极小值 ,三分法求解即可。
class Solution
{
public:
vector<int> arr;
int target;
int calc(int v)
{
int sum = 0;
for (int x : arr)
sum += x > v ? v : x;
return abs(sum - target);
}
int findBestValue(vector<int> &arr, int target)
{
this->arr = arr, this->target = target;
int lb = -1, ub = 1e5 + 1;
while (ub - lb > 1)
{
int mid = (ub + lb) >> 1, mmid = (mid + ub) >> 1;
if (calc(mid) <= calc(mmid))
ub = mmid;
else
lb = mid;
}
if (calc(lb) == calc(ub))
return lb;
return calc(lb) > calc(ub) ? ub : lb;
}
};
暴力
对 a r r arr arr 排序后,设实数 v a l u e ′ value' value′ 满足下式
a b s ( t a r g e t − { ∑ i = 0 k − 1 a r r [ k ] + v a l u e ′ × ( n − k ) } ) = 0 abs(target-\{\sum\limits_{i=0}^{k-1}arr[k]+value'\times (n-k)\})=0 abs(target−{i=0∑k−1arr[k]+value′×(n−k)})=0
此时
v a l u e ′ = ( t a r g e t − ∑ i = 0 k − 1 a r r [ k ] ) / ( n − k ) value'=(target-\sum\limits_{i=0}^{k-1}arr[k])/(n-k) value′=(target−i=0∑k−1arr[k])/(n−k)
遍历一遍 a r r arr arr,找到满足 a r r [ k − 1 ] ≤ v a l u e ′ ≤ a r r [ k ] arr[k-1]\leq value'\leq arr[k] arr[k−1]≤value′≤arr[k] 的 k k k,计算出 v a l u e ′ value' value′ 后四舍五入即为 v a l u e value value。
class Solution
{
public:
int findBestValue(vector<int> &arr, int target)
{
sort(arr.begin(), arr.end());
int sum = 0, n = arr.size();
for (int i = 0; i < n; i++)
{
int v = (target - sum) / (n - i);
if (v < arr[i])
{
double vv = (target - sum) / (double)(n - i);
if (vv - v > 0.5)
return v + 1;
return v;
}
sum += arr[i];
}
return arr[n - 1];
}
};