Given a non-empty integer array, find the minimum number of moves required to make all array elements equal, where a move is incrementing a selected element by 1 or decrementing a selected element by 1.

You may assume the array's length is at most 10,000.

Example:

Input:
[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]

 

LeetCode 453. Minimum Moves to Equal Array Elements —— 最小移动次数使数组元素相等的升级版,但其实个人觉得没啥关系。453题是所有元素向着最小值移动,本题是向着一个未知的目标移动,这个目标使得移动次数最小。直观上就两个选择,数组的平均数或者中位数。这里随便举个例子就能排除平均数,比如[1, 1, 4],平均是2,移动到平均需要4步,而移动到中位数1只需要3步。所以感觉上就是排序,找到中位数,并计算所有元素与中位数差值的和即可。对于证明,数学上肯定是可以的。可这个题想起来其实也非常直观:当数组排好序之后,最大值和最小值的差,也就是排序后第一个元素和最后一个元素的差值,是一定要补满的。以此类推,第二小和第二大的元素的差值,也一定要补满。之后一直向元素的中间推,最后停止的位置就是中位数。所以下面给出两种写法,本质是一样的。

 


解法一(Java)

class Solution {
    public int minMoves2(int[] nums) {
        Arrays.sort(nums);
        int mid = nums[nums.length/2];
        int sum = 0;
        for (int i = 0; i < nums.length; i++) 
            sum += Math.abs(mid - nums[i]);
        return sum;
    }
}

 

解法二(Java)

class Solution {
    public int minMoves2(int[] nums) {
        Arrays.sort(nums);
        int i = 0, j = nums.length -1, sum = 0;
        while (i < j) sum += nums[j--] - nums[i++];
        return sum;
    }
}

 

posted on 2018-08-07 21:54  小T在学习  阅读(281)  评论(0编辑  收藏  举报