给定一个非空整数数组,找到使所有数组元素相等所需的最小移动数,其中每次移动可将选定的一个元素加1或减1。 您可以假设数组的长度最多为10000。
输入:
[1,2,3]
输出:
2
说明:
只有两个动作是必要的(记得每一步仅可使其中一个元素加1或减1):
[1,2,3] => [2,2,3] => [2,2,2]
解答:给数组排序,后取index = n/2 的数据。所有的数朝它靠拢
func minMoves2(_ nums: [Int]) -> Int {
var inNums = nums;
inNums.sort()
let index = inNums.count / 2
let midNum = inNums[index]
var count = 0
for value in inNums {
count += abs(value - midNum)
}
return count
}
算法分析:目标是最少移动次数。默认数组已经排好序
我们将数组数据分为left堆和right堆。将数组最左与最右的两个数据加入堆中。然后每次选择一个堆,从剩余数据的左或右取出数据放入对应堆中(这个堆的数据向另一边靠拢)。可以看出为了移动次数最小每次都会选择left、right中数据较少的堆,它朝另一个堆的方向移动。当任意一个堆取出index为n/2的数据时,它肯定成为数据最多的堆。于是可以认定:所有的数据都朝index为n/2的数据靠拢时,移动次数最小。
网友评论