排序加二分查找解题

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/

欢迎评论后台留言交流~


以上是关于排序加二分查找解题的主要内容,如果未能解决你的问题,请参考以下文章

611. 有效三角形的个数-排序+二分查找

611. 有效三角形的个数-排序+二分查找

611. 有效三角形的个数-排序+二分查找

文巾解题 704. 二分查找

一网打尽!二分查找解题模版与题型全面解析

三道题学会二分查找——javapythonc三种语言解题( ̄▽ ̄)~*