leetcode
leetcode 401 ~ 450
最小操作次数使数组元素相等

最小操作次数使数组元素相等

难度:

标签:

题目描述

给你一个长度为 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

 

提示:

  • n == nums.length
  • 1 <= nums.length <= 105
  • -109 <= nums[i] <= 109
  • 答案保证符合 32-bit 整数

代码结果

运行时间: 31 ms, 内存: 16.9 MB


/**
 * Problem: Given an integer array of length n, each operation increases n - 1 elements by 1.
 * The task is to find the minimum number of operations needed to make all elements equal.
 *
 * Solution Approach:
 * 1. Using Java Streams to find the minimum element and calculate the sum of all elements.
 * 2. The minimum operations required are calculated as the total sum minus n times the minimum element.
 */
 
import java.util.Arrays;
 
public class Solution {
    public int minMoves(int[] nums) {
        int min = Arrays.stream(nums).min().getAsInt();
        int sum = Arrays.stream(nums).sum();
        return sum - nums.length * min;
    }
}

解释

方法:

本题可以转换思路:每次操作将 n - 1 个元素增加 1,等价于每次操作将 1 个元素减少 1。因此,要使所有元素相等,只需要将所有元素减少到数组中的最小值。所以,最小操作次数就是所有元素与最小元素的差值之和。

时间复杂度:

O(n)

空间复杂度:

O(1)

代码细节讲解

🦆
在解释中提到,每次操作将n-1个元素增加1等价于每次操作将1个元素减少1,这种转换的逻辑依据是什么?
这种逻辑依据在于等效的目标变化。在这道题中,使数组所有元素相等的操作可以从两个角度来看:一是增加n-1个元素使其接近最大值,二是减少一个元素使其接近最小值。当你每次增加n-1个元素的值时,实际上是在相对地减小那个没有被增加的元素的值(在视觉上)。换句话说,每次增加大多数元素的同时不增加一个特定元素,相当于所有元素的平均水平上升了,而那个未增加的元素相对于其他元素就减少了。因此,从减少的角度看问题更简单,直接计算将所有元素减少到最小值所需的总步骤数,能够直观地反映操作的实质。
🦆
解法中计算最小操作次数为所有元素与最小元素的差值之和,这种方法是否考虑了数组中可能存在的负数和其对结果的影响?
是的,该解法适用于包含负数的情况。在计算操作次数时,关键在于计算所有元素与最小元素的差值之和。无论最小元素是正数、零还是负数,元素间的差值总和都是不变的。因此,即使数组中包含负数,最小操作次数仍然正确地反映了将所有元素减少到最小值所需的总操作次数。
🦆
你是如何确定只减少到数组中的最小值就是最优解,有没有可能存在更小的操作次数达到目标的情况?
在此问题中,减少到数组中的最小值是最优解,因为每次操作你只能选择减少一个元素,而目标是让所有元素值相等。最小值是数组中自然界限,因为任何小于此的操作会导致至少一个元素需要额外的增加操作来达到新的目标值,这与题目要求相矛盾。因此,选择最小值作为目标是因为这是最自然且操作次数最少的选择。
🦆
代码中使用了`min(nums)`和`sum(nums) - len(nums) * min_val`来计算操作次数,对于极大或极小的输入值,这种方法是否有溢出的风险?
在Python中,整数类型具有自动处理大数的能力,因此在理论上不会出现传统意义上的整数溢出问题。但是,在其他一些编程语言中,如C++或Java,需要考虑数据类型的最大和最小界限,可能会遇到溢出问题。在这些情况下,应当使用足够大的数据类型(如长整型)或者进行额外的检查来确保计算的安全。在Python中,只要内存足够,就可以安全地处理非常大的值。

相关问题

最小操作次数使数组元素相等 II

给你一个长度为 n 的整数数组 nums ,返回使所有数组元素相等需要的最小操作数。

在一次操作中,你可以使数组中的一个元素加 1 或者减 1

 

示例 1:

输入:nums = [1,2,3]
输出:2
解释:
只需要两次操作(每次操作指南使一个元素加 1 或减 1):
[1,2,3]  =>  [2,2,3]  =>  [2,2,2]

示例 2:

输入:nums = [1,10,2,9]
输出:16

 

提示:

  • n == nums.length
  • 1 <= nums.length <= 105
  • -109 <= nums[i] <= 109