📅  最后修改于: 2023-12-03 15:42:02.759000             🧑  作者: Mango
问题描述:给定一个整数数组 nums 和一个整数 k,你需要将 nums 中的元素进行 k 次以下操作:
你需要最小化 nums 中所有元素的和。
示例:
输入: nums = [4,3,1], k = 2
输出: 5
解释:
操作如下:
- 把 nums[0] 减少到 2,数组变成 [2,3,1]。
- 把 nums[1] 减少到 2,数组变成 [2,2,1]。
首先对数组进行排序,从最大值开始向下遍历每个数。对于每个数,我们考虑把从它到它前面的数都变成它本身,所需要减少的次数。如果这个次数大于 k,那么就停止遍历计算。
具体地,假设当前要考虑的数为 nums[i],nums[i-1] 变成 nums[i] 的代价为 i*(nums[i]-nums[i-1])。所以,我们从 i = n-1 开始倒序遍历 nums,对于每个 i,做如下操作:
最终,数组 nums 中所有元素的和就是我们要求的答案。
具体实现请见以下代码:
def min_sum_after_k_operations(nums: List[int], k: int) -> int:
n = len(nums)
nums.sort(reverse=True)
ans = nums[0]
for i in range(1, n):
cost = i * (nums[i-1] - nums[i])
if cost <= k:
ans += i * (nums[i-1] + nums[i]) // 2 * (nums[i-1] - nums[i])
k -= cost
else:
delta = k // i
ans += i * (nums[i-1] + nums[i]) // 2 * (nums[i-1] - delta)
ans += (nums[i-1] - delta) * (k % i)
k -= k
if k <= 0:
break
return ans
代码中有一个排序操作,时间复杂度为 O(n log n),后面的遍历操作的时间复杂度为 O(n),因此总的时间复杂度为 O(n log n)。
不需要额外的空间,空间复杂度为 O(1)。