📌  相关文章
📜  从数组元素中减去以使所有数组元素相等的值的最小总和(1)

📅  最后修改于: 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

以上是两种可行的方法,其中方法一更为高效,但需要理解算法思想,并掌握排序的方法;方法二则是暴力枚举,易于理解但效率相对较低。