其他分享
首页 > 其他分享> > 【数组】力扣453:最小操作次数使数组元素相等

【数组】力扣453:最小操作次数使数组元素相等

作者:互联网

给你一个长度为 n 的整数数组,每次操作将会使 n - 1 个元素增加 1 。返回让数组所有元素相等的最小操作次数。
示例1:

输入:nums = [1,2,3]
输出:3
解释:
只需要3次操作(注意每次操作会增加两个元素的值):
[1,2,3] => [2,3,3] => [3,4,3] => [4,4,4]

示例2:

输入:nums = [1,1,1]
输出:0


利用数学推理很简单:

  1. 假设最少的操作次数是k,k次操作后每个元素相等,相等元素设为target
  2. 对于整个列表的n - 1个元素都要进行加一操作那么增加的总数是 k * (n - 1)
  3. 原本的列表之和为 sum(nums) ,k次操作后应该存在这样的关系等式:
    k[最少操作次数] * (n - 1)[每次对n - 1个元素进行操作] + sum(nums)[原列表的和] = target[操作后的相等元素] * n
    即: k * (n-1) + sum(nums) = target * n

这里最关键的地方是确定target的值,如果我们知道了target的值那么肯定就能知道k,那么target的值是多少呢?
答案是:k + nums中的最小值 即:min(nums) + k
原因:每次操作中必须覆盖最小值,每次的递加都必须对原列表的最小值加一,k次操作后, 最小值就变为了min(nums) + k,该值就是最后的相同值。
k * (n-1) + sum(nums) = (min(nums) + k) * n = min(nums) * n + k * n
公式展开得到
k = sum(nums) - min(nums) * n

class Solution:
    def minMoves(self, nums: List[int]) -> int:
        return sum(nums) - len(nums) * min(nums) if len(nums) != 1 else 0

作者:JonnyHuang
链接:https://leetcode-cn.com/problems/minimum-moves-to-equal-array-elements/solution/python3-yi-xing-dai-ma-ji-bai-99-diao-ch-25ar/

方法2 反向思考
因为只需要找出让数组所有元素相等的最小操作次数,所以我们不需要考虑数组中各个元素的绝对大小,即不需要真正算出数组中所有元素相等时的元素值,只需要考虑数组中元素相对大小的变化即可。
因此,每次操作既可以理解为使 n-1 个元素增加 1,也可以理解为使 1 个元素减少 1。显然,后者更利于我们的计算。
于是,要计算让数组中所有元素相等的操作数,我们只需要计算将数组中所有元素都减少到数组中元素最小值所需的操作数,即计算
image
其中 n 为数组 nums 的长度,min(nums)为数组 nums 中元素的最小值。

在实现中,为避免溢出,我们可以逐个累加每个元素与数组中元素最小值的差,即计算
image

作者:LeetCode-Solution
链接:https://leetcode-cn.com/problems/minimum-moves-to-equal-array-elements/solution/zui-xiao-cao-zuo-ci-shu-shi-shu-zu-yuan-3meg3/

class Solution:
    def minMoves(self, nums: List[int]) -> int:
        ans = 0
        min_num = min(nums)
        for num in nums:
            ans += num - min_num
        return ans

时间复杂度:O(n),其中 n 为数组中的元素数量。我们需要一次遍历求出最小值,一次遍历计算操作次数。
空间复杂度:O(1)。

标签:453,nums,min,元素,力扣,最小值,数组,操作
来源: https://www.cnblogs.com/Jojo-L/p/16077874.html