leetcode_462. Minimum Moves to Equal Array Elements II 移动最小步数使数组各数字相等II,中位数法

来源:互联网 发布:求实软件官网长春 编辑:程序博客网 时间:2024/06/06 07:38

题目:

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:2Explanation:Only two moves are needed (remember each move increments or decrements one element):[1,2,3]  =>  [2,2,3]  =>  [2,2,2]

题意:

给定一个非空整数数组,找到使所有数组元素相等所需的最小移动数,其中移动将所选元素递增1或将所选元素递减1。


代码:

public class Solution {
    public int minMoves2(int[] nums) {
        int n = nums.length;
        if( n <= 1 ){
            return 0;
        }
        else {
            Arrays.sort(nums);    //对数组排序
            int mean = nums[n/2];       //找出中位数,中位数即为数组中下标在中间的数
            int i;
            int res = 0;         //记录移动步数
            for( i = 0; i < n; i++){
                res += Math.abs(nums[i]-mean);       //数组个数字减去中位数,即得移动步数
            }
            return res;
        }
    }
}


笔记:

1、刚开始本人计算整个数组的平均数,然后用每个数减去平均数,相加求和,得到最后的移动步数。提交后提示答案不对,网上参考了答案,要找中位数,仔细分析了下,发现出错原因如下:这个题的关键是找一个数,竖立一个靶子,然后所有的数都往这个靶子靠近。

 如果数组个数是偶数,那么用这种方法计算是没有问题的,因为这时数组的中位数位置在两个数中间,平均数也在这两个数中间,因此无论这个中间数是取中位数的上下区间的数,或者取平均数,移动的步数都相等; 

但如果数组个数是奇数,这时中位数位置是确定的。这时中位数两边的数个数相等,无论他们往哪个数字上移动,最后的移动步数都是相等的,即中位数两边的数移动的步数是确定的;因此,次数总的移动步数,就看中位数的移动了。如果都往中位数上移,那中位数移动步数为0,其他数字移动步数确定,总的移动步数就是最小的。

这个题找中位数的数学证明如下:
先将数组按递增的顺序排好序,y1:移动到数组第k个下标的移动步数      y2:移动到数组的中间(移动到数组中位数)的移动步数
y1y1

 y1=i=0k(akai)i=k+1naiak,kn2
 y2=i=0n2(an2ai)i=n2+1naian2
假设k>n2,即ak=an2+x,x>0, 
y1y2=i=n2+1k(akai)+n2×x+i=n2+1k(aian2)+(kn)×x=i=n2+1k(akan2)+(kn2)×x=(2kn)×x>0

同理,当ak<an2时,也比y2大。 
因此,如果取得不是中位数,最后的结果都会比这大。

参考:y1http://blog.csdn.net/liuchenjane/article/details/53244689

y1
0 0
原创粉丝点击