轉變數組後最接近目標值的數組和

轉變數組後最接近目標值的數組和

給你一個整數數組 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
解釋:當選擇 value 爲 5 時,數組會變成 [2,3,5],2+3+5=10  ,這時兩者相等,兩者之差爲0)。

示例 3:

輸入:arr = [60864,25176,27249,21296,20204], target = 56803
輸出:11361
解釋:當選擇 value 爲 11361 時,[11361,11361,11361,11361,11361],數組之和爲56805,兩者之差爲2。

提示:

1 <= arr.length <= 10^4
1 <= arr[i], target <= 10^5

代碼

public class Solution {

    public int findBestValue(int[] arr, int target) {
        int left = 0;
        int right = 0;
        // 注意:
        for (int num : arr) {
            right = Math.max(right, num);
        }

        while (left < right) {
            int mid = left + (right - left + 1) / 2;
            int sum = calculateSum(arr, mid);
            // 計算最後 1 個使得轉變以後數組的和小於等於 target 的閾值 threshold
            if (sum > target) {
                // 大於等於的就不是解,threshold 太大了,下一輪搜索區間是 [left, mid - 1]
                right = mid - 1;
            } else {
                // 下一輪搜索區間是 [mid, right]
                left = mid;
            }
        }

        // 比較閾值線分別定在 left 和 left + 1 的時候與 target 的接近程度
        int sum1 = calculateSum(arr, left);
        int sum2 = calculateSum(arr, left + 1);
        // 注意:這裏必須加絕對值,因爲有可能出現 sum1 == sum2 < target 的情況
        if (Math.abs(target - sum1) <= Math.abs(sum2 - target)) {
            return left;
        }
        return left + 1;
    }

    private int calculateSum(int[] arr, int threshold) {
        int sum = 0;
        for (int num : arr) {
            sum += Math.min(num, threshold);
        }
        return sum;
    }

    public static void main(String[] args) {
        int[] arr = new int[]{2, 3, 5};
        int target = 11;
        Solution solution = new Solution();
        int res = solution.findBestValue(arr, target);
        System.out.println(res);
    }
}

來自liweiwei1419

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章