您的位置:首页 > 其它

(9)1300. 转变数组后最接近目标值的数组和

2020-07-16 04:32 85 查看
题目链接:https://leetcode-cn.com/problems/sum-of-mutated-array-closest-to-target/
困难度:中
1300. 转变数组后最接近目标值的数组和
给你一个整数数组 arr 和一个目标值 target ,请你返回一个整数
value ,使得将数组中所有大于 value 的值变成 value 后,数组的
和最接近  target (最接近表示两者之差的绝对值最小)。
如果有多种使得和最接近 target 的方案,请你返回这些整数中的
最小值。请注意,答案不一定是 arr 中的数字。
示例 1:
输入:arr = [4,9,3], target = 10
输出:3
解释:当选择 value 为 3 时,数组会变成 [3, 3, 3],和为 9 ,这是最接近 target 的方案。
示例 2:
输入:arr = [2,3,5], target = 10
输出:5
示例 3:
输入:arr = [60864,25176,27249,21296,20204], target = 56803
输出:11361
提示
1 <= arr.length <= 10^4
1 <= arr[i], target <= 10^5

还是不会做 ,和之前做过的编程题相比 难!。。。 也就简单的还有可能做出来。。。哎。 看了看思路 大概理解了

class Solution {
public:
int findBestValue(vector<int>& arr, int target) {
// 对vector进行排序
sort(arr.begin(), arr.end());
// 获取长度
int n = arr.size();
//拿到数组中最大值
int max = arr[n - 1];
// 用来保存对应的前缀 pre[0]=0  pre
=数组之和
// 典型的空间换时间
vector<int> pre(n + 1);
for (int i = 1; i <= n; i++) {
pre[i] = pre[i - 1] + arr[i - 1];
}

//ans 记录返回的数
int ans = 0;
//dif 相差的值
int dif = target;
//循环范围为 1-max
//为0的话 该数组和为0
//大于max失去意义 数组内的数字不会在变化
for (int i = 1; i <= max; ++i) {
//lower_boundlower_bound( begin,end,num)
//从数组的begin位置到end-1位置二分查找第一个大于或等于num的数字
//找到返回该数字的地址,不存在则返回end。
//f返回的it-arr.begin() 即为数组下标
// 还有一个函数叫upper_bound  返回第一个大于的数
//这两个函数 使用方法为 二分查找
auto it = lower_bound(arr.begin(), arr.end(), i);
int j = it - arr.begin();
//sum 为当数为i时的 和
int sum = pre[j] + (n - j) * i;
if (abs(sum - target) < dif) {
ans = i;
dif = abs(sum - target);
}
}
return ans;
}
};

还有一种

class Solution {
public:
int findBestValue(vector<int>& arr, int target) {
sort(arr.begin(), arr.end());
int n = arr.size();
int max = arr[n - 1];
vector<int> pre(n + 1);

for (int i = 1; i <= n; i++) {
pre[i] = pre[i - 1] + arr[i - 1];
}

int l = 0;
int ans = -1;
int cur = 0;
while (l <= max) {
int mid = (l + max) / 2;
auto iter = lower_bound(arr.begin(), arr.end(), mid);
cur = pre[iter - arr.begin()] + (arr.end() - iter) * mid;
if (cur <= target) {
ans = mid;
l = mid + 1;
}
else
{
max = mid - 1;
}
}
auto it1 = lower_bound(arr.begin(), arr.end(), ans);
int small = pre[it1 - arr.begin()] + (arr.end() - it1) * (ans);

auto it = lower_bound(arr.begin(), arr.end(), ans+1);
int big = pre[it - arr.begin()] + (arr.end() - it) * (ans+1);

return abs(small - target) <= abs(big - target) ? ans : ans + 1;
}
};
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐