[LeetCode] 1300. Sum of Mutated Array Closest to Target

Given an integer array arr and a target value target, return the integer value such that when we change all the integers larger than value in the given array to be equal to value, the sum of the array gets as close as possible (in absolute difference) to target.

In case of a tie, return the minimum such integer.

Notice that the answer is not necessarily a number from arr

Example 1:

Input: arr = [4,9,3], target = 10
Output: 3
Explanation: When using 3 arr converts to [3, 3, 3] which sums 9 and that's the optimal answer.

Example 2:

Input: arr = [2,3,5], target = 10
Output: 5

Example 3:

Input: arr = [60864,25176,27249,21296,20204], target = 56803
Output: 11361

Constraints:

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

转变数组后最接近目标值的数组和。题意是给一个数组和一个数字target,请你返回一个整数value,使得数组中所有比这个value大的数字被换成value之后,数组中所有数字的和sum最接近于target。比如第一个例子,把所有大于3的数字换成3之后,数组的和是9,最接近于给定的target10。

思路是二分法。首先遍历input数组,得到数组所有元素的和sum以及数组中最大的数字max。需要寻找的这个res一定介于0 - max之间。为什么呢?因为被修改的数字一定是需要小于value的,如果这个value大于数组中的最大元素,意味着没有任何一个数字被修改过,所以value大于max是不成立的。所以在0 - max之间做二分搜索,并且每找到一个mid,就算一次sum和,二分法逼近最接近target的sum之后,找到对应的mid即可。

时间O(nlogn)

空间O(1)

Java实现

 1 class Solution {
 2     public int findBestValue(int[] arr, int target) {
 3         int sum = 0;
 4         int max = Integer.MIN_VALUE;
 5         for (int a : arr) {
 6             sum += a;
 7             max = Math.max(max, a);
 8         }
 9         if (sum == target) return max;
10         int min = 0, res = 1,diff = Integer.MAX_VALUE;
11         // The answer would lie between 0 and maximum value in the array.
12         while (min <= max) {
13             int mid = min + (max - min) / 2;
14             sum = getMutatedSum(arr, mid); 
15             if (sum > target) {
16                 max = mid - 1;
17             } else {
18                 min = mid + 1;
19             }
20             // If current difference is less than diff || current difference==diff but mid < res.(choose the smaller one.)
21             if (Math.abs(sum - target) < diff || (Math.abs(sum - target) == diff && mid < res)) { 
22                 res = mid;
23                 diff = Math.abs(sum - target);
24             }
25         }
26         return res;
27     }
28     
29     private int getMutatedSum(int[] arr, int mid) {
30         int sum = 0;
31         for (int a : arr) {
32             sum += (a > mid) ? mid : a;
33         }
34         return sum;
35     }
36 }

 

LeetCode 题目总结

posted @ 2020-06-15 05:10  CNoodle  阅读(319)  评论(0编辑  收藏  举报