Files
2021-05-20 23:55:27 +08:00

66 lines
1.9 KiB
Markdown
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# [462. Minimum Moves to Equal Array Elements II](https://leetcode.com/problems/minimum-moves-to-equal-array-elements-ii/)
## 题目
Given an integer array `nums` of size `n`, return *the minimum number of moves required to make all array elements equal*.
In one move, you can increment or decrement an element of the array by `1`.
**Example 1:**
```
Input: nums = [1,2,3]
Output: 2
Explanation:
Only two moves are needed (remember each move increments or decrements one element):
[1,2,3] => [2,2,3] => [2,2,2]
```
**Example 2:**
```
Input: nums = [1,10,2,9]
Output: 16
```
**Constraints:**
- `n == nums.length`
- `1 <= nums.length <= 10^5`
- `109 <= nums[i] <= 10^9`
## 题目大意
给定一个非空整数数组,找到使所有数组元素相等所需的最小移动数,其中每次移动可将选定的一个元素加 1 或减 1。 您可以假设数组的长度最多为10000。
## 解题思路
- 这题抽象成数学问题是,如果我们把数组 a 中的每个数看成水平轴上的一个点,那么根据上面的移动次数公式,我们需要找到在水平轴上找到一个点 x使得这 N 个点到 x 的距离之和最小。有 2 个点值得我们考虑,一个是中位数,另外一个是平均值。举个简单的例子,[1,0,0,8,6] 这组数据,中位数是 1平均值是 3 。分别计算移动的步数,按照中位数对齐是 14按照平均值对齐是 16 。所以选择中位数。
- 此题可以用数学证明,证明出,按照平均值移动的步数 ≥ 按照中位数移动的步数。具体证明笔者这里不证明了,感兴趣的同学可以自己证明试试。
## 代码
```go
package leetcode
import (
"math"
"sort"
)
func minMoves2(nums []int) int {
if len(nums) == 0 {
return 0
}
moves, mid := 0, len(nums)/2
sort.Ints(nums)
for i := range nums {
if i == mid {
continue
}
moves += int(math.Abs(float64(nums[mid] - nums[i])))
}
return moves
}
```