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

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

    返回一个序列中满足某个条件的最小值,那么就可以想到二分。

    int l, r;
    while (l < r) {
        int mid = l + r >> 1;
        if (check(mid)) r = mid;
        else l = mid + 1;
        return l;  // l就是满足check(mid)的第一个值
    }
    

    先对原数组排序。

    那么下一步就是思考二分的区间,按照题目的意思,可以直接将l设为a[0]r设为a[n - 1]。但是有点太暴力了。

    其实想一想,我们可以发现 选组数组中两个相邻数(a[k - 1], a[k])之间的所有数(t)的数组和表达式:

    $ a[0] + a[1] + ... + a[k - 1] + t * (n - k)$中,(0, k - 1)的前缀和sum,与t的项数n - k是固定的。

    这样我们就可以在一个固定区间内,用一个固定的表达式,用二分法求出最优解。

    进一步,我们还可以确定出最优解一定在某一个区间中。假设k是满足$ (a[0] + a[1] + ... a[k - 1]) + a[k] * (n - k) >= target\(的最小值,那么答案就一定在\)[a[k-1], a[k]]$中。

    class Solution {
    public:
    
        int findBestValue(vector<int>& a, int target) {
            int n = a.size();
    
            sort(a.begin(), a.end());
            
            int k = 0, sum = 0;
            // 找到二分搜索区间, k是满足 (a[0] + a[1] + ... a[k - 1]) + a[k] * (n - k) >= target的最小值
            // 那么答案一定在[a[k - 1], a[k]] 中
            while ( k < n && a[k] * (n - k)  + sum < target) {  
                sum += a[k];
                k++;
            }
            
            if (k >= n) return a[n - 1];
            
            int l = 0, r = a[k];
            if (k) l = a[k - 1];
            
            while (l < r) {  
                int mid = l + r >> 1;
                int val = sum + mid * (n - k);
                if (val >= target) r = mid;
                else l = mid + 1;
            }
            
            // l 是 >= target的第一个数, l - 1是 < target的第一个数
            int left = abs(sum + (l - 1) * (n - k) - target), right = abs(sum + l * (n - k) - target);
    
            if (left <= right) return l - 1;
            else return l;
        }
    };
    
  • 相关阅读:
    未完存储过程MySQL
    看山不是山——我们眼中的世界并不可观
    常用Linux命令
    表格行列的删除
    RFID会议签到系统总结(二十一)――服务端的通讯
    FastReport的一些另类用法
    RFID会议签到系统总结(二十二)――系统中的模式
    单元格的计算
    表格行列的移动
    RFID会议签到系统总结(十九)――单数据窗体
  • 原文地址:https://www.cnblogs.com/macguz/p/14383272.html
Copyright © 2011-2022 走看看