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

This commit is contained in:
huangge1199 2021-10-20 15:21:16 +08:00
parent dce12c390b
commit 715358c66c
4 changed files with 206 additions and 1 deletions

View File

@ -0,0 +1,59 @@
//给你一个长度为 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 <= 10
// -10 <= nums[i] <= 10
// 答案保证符合 32-bit 整数
//
// Related Topics 数组 数学 👍 326 👎 0
package leetcode.editor.cn;
import java.util.Arrays;
//453:最小操作次数使数组元素相等
class MinimumMovesToEqualArrayElements {
public static void main(String[] args) {
//测试代码
Solution solution = new MinimumMovesToEqualArrayElements().new Solution();
}
//力扣代码
//leetcode submit region begin(Prohibit modification and deletion)
class Solution {
public int minMoves(int[] nums) {
int min = Arrays.stream(nums).min().getAsInt();
int count = 0;
for (int num : nums) {
count += num-min;
}
return count;
}
}
//leetcode submit region end(Prohibit modification and deletion)
}

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,32 @@
<p>给你一个长度为 <code>n</code> 的整数数组,每次操作将会使 <code>n - 1</code> 个元素增加 <code>1</code> 。返回让数组所有元素相等的最小操作次数。</p>
<p>&nbsp;</p>
<p><strong>示例 1</strong></p>
<pre>
<strong>输入:</strong>nums = [1,2,3]
<strong>输出:</strong>3
<strong>解释:</strong>
只需要3次操作注意每次操作会增加两个元素的值
[1,2,3] =&gt; [2,3,3] =&gt; [3,4,3] =&gt; [4,4,4]
</pre>
<p><strong>示例 2</strong></p>
<pre>
<strong>输入:</strong>nums = [1,1,1]
<strong>输出:</strong>0
</pre>
<p>&nbsp;</p>
<p><strong>提示:</strong></p>
<ul>
<li><code>n == nums.length</code></li>
<li><code>1 &lt;= nums.length &lt;= 10<sup>5</sup></code></li>
<li><code>-10<sup>9</sup> &lt;= nums[i] &lt;= 10<sup>9</sup></code></li>
<li>答案保证符合 <strong>32-bit</strong> 整数</li>
</ul>
<div><div>Related Topics</div><div><li>数组</li><li>数学</li></div></div><br><div><li>👍 326</li><li>👎 0</li></div>

View File

@ -0,0 +1,114 @@
#### 方法一:数学
**思路和算法**
因为只需要找出让数组所有元素相等的最小操作次数,所以我们不需要考虑数组中各个元素的绝对大小,即不需要真正算出数组中所有元素相等时的元素值,只需要考虑数组中元素相对大小的变化即可。
因此,每次操作既可以理解为使 $n-1$ 个元素增加 $1$,也可以理解使 $1$ 个元素减少 $1$。显然,后者更利于我们的计算。
于是,要计算让数组中所有元素相等的操作数,我们只需要计算将数组中所有元素都减少到数组中元素最小值所需的操作数,即计算
$$
\sum_^ \textit[i] - min(\textit) * n
$$
其中 $n$ 为数组 $\textit{nums}$ 的长度,$\textit(\textit)$为数组 $\textit{nums}$ 中元素的最小值。
在实现中,为避免溢出,我们可以逐个累加每个元素与数组中元素最小值的差,即计算
$$
\sum_^ (\textit[i] - \textit(\textit))
$$
**代码**
* [sol1-Python3]
```Python
class Solution:
def minMoves(self, nums: List[int]) -> int:
min_num = min(nums)
res = 0
for num in nums:
res += num - min_num
return res
```
* [sol1-Java]
```Java
class Solution {
public int minMoves(int[] nums) {
int minNum = Arrays.stream(nums).min().getAsInt();
int res = 0;
for (int num : nums) {
res += num - minNum;
}
return res;
}
}
```
* [sol1-C#]
```C#
public class Solution {
public int MinMoves(int[] nums) {
int minNum = nums.Min();
int res = 0;
foreach (int num in nums) {
res += num - minNum;
}
return res;
}
}
```
* [sol1-C++]
```C++
class Solution {
public:
int minMoves(vector<int>& nums) {
int minNum = *min_element(nums.begin(),nums.end());
int res = 0;
for (int num : nums) {
res += num - minNum;
}
return res;
}
};
```
* [sol1-Golang]
```go
func minMoves(nums []int) (ans int) {
min := nums[0]
for _, num := range nums[1:] {
if num < min {
min = num
}
}
for _, num := range nums {
ans += num - min
}
return
}
```
* [sol1-JavaScript]
```JavaScript
var minMoves = function(nums) {
const minNum = Math.min(...nums);
let res = 0;
for (const num of nums) {
res += num - minNum;
}
return res;
};
```
**复杂度分析**
- 时间复杂度:$O(n)$,其中 $n$ 为数组中的元素数量。我们需要一次遍历求出最小值,一次遍历计算操作次数。
- 空间复杂度:$O(1)$。