comments | difficulty | edit_url | rating | source | tags | ||||
---|---|---|---|---|---|---|---|---|---|
true |
中等 |
1903 |
第 338 场周赛 Q3 |
|
给你一个正整数数组 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 <= 105
1 <= nums[i], queries[i] <= 109
我们先将数组
接下来,遍历每个查询
我们可以通过二分查找找到数组
同理,我们可以找到数组
最后,将这两个总操作次数相加,即为将数组
时间复杂度
class Solution:
def minOperations(self, nums: List[int], queries: List[int]) -> List[int]:
nums.sort()
s = list(accumulate(nums, initial=0))
ans = []
for x in queries:
i = bisect_left(nums, x + 1)
t = s[-1] - s[i] - (len(nums) - i) * x
i = bisect_left(nums, x)
t += x * i - s[i]
ans.append(t)
return ans
class Solution {
public List<Long> minOperations(int[] nums, int[] queries) {
Arrays.sort(nums);
int n = nums.length;
long[] s = new long[n + 1];
for (int i = 0; i < n; ++i) {
s[i + 1] = s[i] + nums[i];
}
List<Long> ans = new ArrayList<>();
for (int x : queries) {
int i = search(nums, x + 1);
long t = s[n] - s[i] - 1L * (n - i) * x;
i = search(nums, x);
t += 1L * x * i - s[i];
ans.add(t);
}
return ans;
}
private int search(int[] nums, int x) {
int l = 0, r = nums.length;
while (l < r) {
int mid = (l + r) >> 1;
if (nums[mid] >= x) {
r = mid;
} else {
l = mid + 1;
}
}
return l;
}
}
class Solution {
public:
vector<long long> minOperations(vector<int>& nums, vector<int>& queries) {
sort(nums.begin(), nums.end());
int n = nums.size();
vector<long long> s(n + 1);
for (int i = 0; i < n; ++i) {
s[i + 1] = s[i] + nums[i];
}
vector<long long> ans;
for (auto& x : queries) {
int i = lower_bound(nums.begin(), nums.end(), x + 1) - nums.begin();
long long t = s[n] - s[i] - 1LL * (n - i) * x;
i = lower_bound(nums.begin(), nums.end(), x) - nums.begin();
t += 1LL * x * i - s[i];
ans.push_back(t);
}
return ans;
}
};
func minOperations(nums []int, queries []int) (ans []int64) {
sort.Ints(nums)
n := len(nums)
s := make([]int, n+1)
for i, x := range nums {
s[i+1] = s[i] + x
}
for _, x := range queries {
i := sort.SearchInts(nums, x+1)
t := s[n] - s[i] - (n-i)*x
i = sort.SearchInts(nums, x)
t += x*i - s[i]
ans = append(ans, int64(t))
}
return
}
function minOperations(nums: number[], queries: number[]): number[] {
nums.sort((a, b) => a - b);
const n = nums.length;
const s: number[] = new Array(n + 1).fill(0);
for (let i = 0; i < n; ++i) {
s[i + 1] = s[i] + nums[i];
}
const search = (x: number): number => {
let l = 0;
let r = n;
while (l < r) {
const mid = (l + r) >> 1;
if (nums[mid] >= x) {
r = mid;
} else {
l = mid + 1;
}
}
return l;
};
const ans: number[] = [];
for (const x of queries) {
const i = search(x + 1);
let t = s[n] - s[i] - (n - i) * x;
const j = search(x);
t += x * j - s[j];
ans.push(t);
}
return ans;
}