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]
题目理解:
给定一个数组,定义一个move为将一个元素增大或者减小1,问最少经过多少个move,才能将所有的元素变得相同
解题思路:
首先对数组进行排序,计算将所有元素变为某一个元素的最小move数,排在该元素之前的元素一定会变大(或者不变),排在该元素之后的元素一定减小(或者不变),因此,只需要计算出该元素之前所有元素的和,以及该元素之后所有元素的和,减去所有元素都是当前元素时的和,就能够知道将所有元素变为当前元素的最小move数。
计算指定区间和的方法,是对于每一个位置i,计算出0至i的元素的和,然后做减法。
代码如下:
class Solution {
public int minMoves2(int[] nums) {
Arrays.sort(nums);
int len = nums.length;
long[] sums = new long[len];
int res = Integer.MAX_VALUE;
sums[0] = nums[0];
for(int i = 1; i < len; i++)
sums[i] = nums[i] + sums[i - 1];
for(int i = 0; i < len; i++){
if(i == 0){
long temp = sums[len - 1] - (long)nums[0] * len;
if(temp < res)
res = (int)temp;
}
else if( i == len - 1){
long temp = (long)nums[len - 1] * len - sums[len - 1];
if(temp < res)
res = (int)temp;
}
else {
long temp = (long)nums[i] * i - sums[i - 1] + (sums[len - 1] - sums[i] - (long)nums[i] * (len - i - 1));
if(temp < res)
res = (int)temp;
}
}
return res;
}
}