排序加二分查找解题
Posted 力扣日记
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了排序加二分查找解题相关的知识,希望对你有一定的参考价值。
给你一个整数数组 arr 和一个目标值 target ,请你返回一个整数 value ,使得将数组中所有大于 value 的值变成 value 后,数组的和最接近 target(最接近表示两者之差的绝对值最小)。
如果有多种使得和最接近 target 的方案,请你返回这些整数中的最小值。
请注意,答案不一定是 arr 中的数字。
题解:
1.一个整数数组 arr 和一个目标值 target
2.将数组中所有大于 value 的值变成 value
3.数组的和与target之差的绝对值最小
4.如果有多个value使数组和接近target,返回整数最小的
示例 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
解题思路:
先对数组从小到大进行排序
从前向后遍历每一个元素,试探当以arr[i]为value时,数组和距离target的距离
当以arr[i]为value时,数组和为前i个元素之和+arr[i]*(length-i),因为arr[i]之后的元素都更新为arr[i]的值
如此遍历下去如果数组和大于target,则可以停止继续向下试探
其次是如果有多种方案,保留值小的用找到的当前value大1的比较
如果当前值value更接近target或当前值value和value加1的值距离target相等,返回value,因为value是更小的方案;否则返回value+1
C/C++题解:
class Solution {
public:
int findBestValue(vector<int>& arr, int target) {
sort(arr.begin(), arr.end());//从小到大排序
int n = arr.size();
vector<int> prefix(n + 1);//用一个数组记录前i个元素和
for (int i = 1; i <= n; i ++) {
prefix[i] = prefix[i - 1] + arr[i - 1];}
int r = arr[n-1];//r为元素最大值
int ans = 0, diff = target;
for (int i = 1; i <= r;i ++) {
auto iter = lower_bound(arr.begin(), arr.end(), i);
int cur = prefix[iter - arr.begin()] + (arr.end() - iter) * i;
if (abs(cur - target) < diff) {//如果绝对值差更小,距离target越近
ans = i; //记录这个value
diff = abs(cur - target);} }//同时更新误差
return ans;}};//value
Debug结果:
Java题解:
class Solution {
public int findBestValue(int[] arr, int target) {
Arrays.sort(arr);//从小到大排序
int n = arr.length;
int[] prefix = new int[n + 1];//用一个数组记录前i个元素和
for (int i = 1; i <= n; i ++) {
prefix[i] = prefix[i - 1] + arr[i - 1]; }
int r = arr[n-1];//r为元素最大值
int ans = 0, diff = target;
for (int i = 1; i <= r;i ++) {
//二分查找第一个大于或等于num的数字,找到返回下标,不存在返回-1
int iter = Arrays.binarySearch(arr, i);
if (iter < 0) { iter = -iter - 1;}
int cur = prefix[iter] + (n - iter) * i;
if (Math.abs(cur - target) < diff) {//如果绝对值差更小,距离target越近
ans = i; //记录这个value
diff = Math.abs(cur - target);}}//同时更新误差
return ans;}}//value
Debug结果:
Python题解:
class Solution(object):
def findBestValue(self, arr, target):
""":type arr: List[int]:type target: int:rtype: int"""
arr.sort() #从小到大排序
n = len(arr)
prefix = [0]*(n + 1) #用一个数组记录前i个元素和
for i in range(1, n+1):
prefix[i] = prefix[i - 1] + arr[i - 1]
r = arr[n-1] #r为元素最大值
ans, diff = 0, target
for i in range(1, r+1):
#二分查找x存在时返回x左侧的位置,x不存在返回应该插入的位置
idx = bisect.bisect_left(arr, i)
cur = prefix[idx] + (n - idx) * i; #数组和
if abs(cur - target) < diff: #如果绝对值差更小,距离target越近
ans = i #记录这个value
diff = abs(cur - target) #同时更新误差
return ans #value
Debug结果:
例题来自力扣网https://leetcode-cn.com/
欢迎评论后台留言交流~
以上是关于排序加二分查找解题的主要内容,如果未能解决你的问题,请参考以下文章