📅  最后修改于: 2023-12-03 15:36:18.781000             🧑  作者: Mango
有一个长度为 n 的整数数组,你需要对它执行一些操作。每次操作可以选择数组中的一个元素,并将所有其他元素增加 1。你需要通过若干次操作使得数组中的所有元素相等。
请编写一个函数,计算并返回将数组元素变为相等值所需的最小操作数。
输入: [1,2,3]
输出: 3
解释:
只需要进行3次操作:将第2个数变为1,第3个数变为2,数组变为[1, 1, 1]。
显然,我们需要将数组中的所有元素都变为它们的平均值。设数组的平均值为 m,那么我们得到:
sum(nums) - n * m
其中 sum(nums) 表示数组中所有元素的和。
算法基于排序,首先将数组排序,然后每次找到一个前缀和后缀,计算当前的平均数,如果平均数小于当前数,则继续移动另一个指针;否则,移动当前指针。这类似于双指针的方法。
时间复杂度:O(nlogn)。排序需要 O(nlogn) 的时间复杂度,扫描数组还需要 O(n) 的时间复杂度。
class Solution:
def minMoves(self, nums: List[int]) -> int:
n = len(nums)
nums.sort()
i = 0
j = n - 1
res = 0
while i < j:
res += nums[j] - nums[i]
i += 1
j -= 1
return res
对于每个元素,我们需要将它加上 (max(nums) - min(nums)) 才能使数组中的所有元素相等。
时间复杂度:O(n^2)。
class Solution:
def minMoves(self, nums: List[int]) -> int:
res = 0
while len(set(nums)) != 1:
max_num = max(nums)
min_num = min(nums)
for i in range(len(nums)):
if nums[i] != max_num:
nums[i] += max_num - min_num
res += max_num - min_num
return res
以上是两种可行的方法,其中方法一更为高效,但需要理解算法思想,并掌握排序的方法;方法二则是暴力枚举,易于理解但效率相对较低。