zoukankan      html  css  js  c++  java
  • [1300. 转变数组后最接近目标值的数组和]

    [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
    public int findBestValue(int[] arr, int target) {
        //从小到大排序
            Arrays.sort(arr);
        //计算前缀和
            int sum = 0;
    	
            for (int i = 0; i < arr.length; i++) {
                //计算还未加上部分的最佳平均值,当小数部分等于0.5时,只能向左取值
                int x = (int)( (double)(target-sum)/(arr.length-i)+0.499999);
    			
                //如果平均值小于等于当前值,也就是说后续的值只会越来越大,截断值为当前平均值最接近target
                if(x <= arr[i]){
                    return x;
                }
                sum += arr[i];
            }
        //此时说明数组所有值相加小于target,返回数组最大值
            return arr[arr.length-1];
        }
    

    另一种思路是二分查找截断值,可以很容易找到两个边界,target/arr.size()arr.max(),如果target/arr.size() 大于 arr.max(),说明数组和小于target,返回arr.max()

     public int findBestValue(int[] arr, int target) {
    
            int average = (int)( (double)target/arr.length+0.49999);
            int max = 0;
            for (int i : arr) {
                if(i > max) {
                    max = i;
                }
            }
    
            if(max < average){
                return max;
            }
    
            int sum = 0;
            while (average < max){
                sum = 0;
                int median = (average+max)/2;
                for (int i : arr) {
                    if(i > median) {
                        sum += median;
                    }else {
                        sum += i;
                    }
                }
                if(sum <= target){
                    average = median+1;
                }else {
                    max = median;
                }
            }
            sum = 0;
            for (int i : arr) {
                if(i > average){
                    sum += average;
                }else {
                    sum += i;
                }
            }
    
            int tmp = 0;
            for (int i : arr) {
                if(i > average-1){
                    tmp += average-1;
                }else {
                    tmp += i;
                }
            }
    
            if(Math.abs(target - tmp) >Math.abs(sum - target)){
                return average;
            }else {
                return average-1;
            }
        }
    
    因为我喜欢追寻过程中的自己
  • 相关阅读:
    css篇-less,scss 用calc问题
    工具篇-Mac上搭建本地svn服务器以及使用Cornerstone进行本地版本控制
    小程序篇-开发工具报错
    js篇-json字符串与json对象相互转化
    小程序篇- data 数据绑定
    RN-android 打包后,部分图片不显示
    asxios--form data提交,setcookie
    RN-系列
    纯css 实现横向滚动条--移动端
    Oralce给字段追加字符,以及oracle 给字段替换字符
  • 原文地址:https://www.cnblogs.com/IzuruKamuku/p/14359769.html
Copyright © 2011-2022 走看看