给你一个正整数数组 nums
。
同时给你一个长度为 m
的整数数组 queries
。第 i
个查询中,你需要将 nums
中所有元素变成 queries[i]
。你可以执行以下操作 任意 次:
- 将数组里一个元素 增大 或者 减小
1
。
请你返回一个长度为 m
的数组 answer
,其中 answer[i]
是将 nums
中所有元素变成 queries[i]
的 最少 操作次数。
注意,每次查询后,数组变回最开始的值。
示例 1:
输入:nums = [3,1,6,8], queries = [1,5] 输出:[14,10] 解释:第一个查询,我们可以执行以下操作: - 将 nums[0] 减小 2 次,nums = [1,1,6,8] 。 - 将 nums[2] 减小 5 次,nums = [1,1,1,8] 。 - 将 nums[3] 减小 7 次,nums = [1,1,1,1] 。 第一个查询的总操作次数为 2 + 5 + 7 = 14 。 第二个查询,我们可以执行以下操作: - 将 nums[0] 增大 2 次,nums = [5,1,6,8] 。 - 将 nums[1] 增大 4 次,nums = [5,5,6,8] 。 - 将 nums[2] 减小 1 次,nums = [5,5,5,8] 。 - 将 nums[3] 减小 3 次,nums = [5,5,5,5] 。 第二个查询的总操作次数为 2 + 4 + 1 + 3 = 10 。
示例 2:
输入:nums = [2,9,6,3], queries = [10] 输出:[20] 解释:我们可以将数组中所有元素都增大到 10 ,总操作次数为 8 + 1 + 4 + 7 = 20 。
提示:
n == nums.length
m == queries.length
1 <= n, m <= 10^5
1 <= nums[i], queries[i] <= 10^9
提示 1
For each query, you should decrease all elements greater than queries[i] and increase all elements less than queries[i].
提示 2
The answer is the sum of absolute differences between queries[i] and every element of the array. How do you calculate that optimally?
解法1:前缀和 + 二分查找 + 距离和 + 哈希表
类似题型:LeetCode 1685. 有序数组中差绝对值之和-CSDN博客
Java版:
class Solution {
public List<Long> minOperations(int[] nums, int[] queries) {
int n = nums.length;
Arrays.sort(nums);
long[] presum = new long[n + 1];
for (int i = 0; i < n; i++) {
presum[i + 1] = (long) presum[i] + nums[i];
}
int m = queries.length;
List<Long> ans = new ArrayList<>(m);
for (int i = 0; i < m; i++) {
int target = queries[i];
int j = binarySearch(nums, target);
long a = (long) target * (j + 1) - presum[j + 1] + presum[n] - presum[j + 1] - (long) target * (n - 1 - j);
ans.add(a);
}
return ans;
}
private int binarySearch(int[] nums, int target) {
int l = 0;
int r = nums.length - 1;
while (l <= r) {
int mid = l + (r - l) / 2;
if (nums[mid] < target) {
l = mid + 1;
} else {
r = mid - 1;
}
}
return r;
}
}
Python3版:
class Solution:
def minOperations(self, nums: List[int], queries: List[int]) -> List[int]:
def binarySearch(nums, target, l, r):
while l <= r:
mid = l + (r - l) // 2
if nums[mid] < target:
l = mid + 1
else:
r = mid - 1
return r
n = len(nums)
nums.sort()
presum = [0] * (n + 1)
for i in range(n):
presum[i + 1] = presum[i] + nums[i]
m = len(queries)
ans = []
for q in queries:
i = binarySearch(nums, q, 0, n - 1)
ans.append(q * (2 * i + 2 - n) - presum[i + 1] + presum[n] - presum[i + 1])
return ans
复杂度分析
时间复杂度:O((n+m)logn),其中 n 为 nums 的长度,m 为 queries 的长度。。
空间复杂度:O(n+m)。