给定一个非空整数数组,找到使所有数组元素相等所需的最小移动数,其中每次移动可将选定的一个元素加1或减1。 您可以假设数组的长度最多为10000。
例如:
输入:
[1,2,3]
输出:
2
说明:
只有两个动作是必要的(记得每一步仅可使其中一个元素加1或减1):
[1,2,3] => [2,2,3] => [2,2,2]
package com.loo;
import java.util.Arrays;
public class MinMoveNumber {
public static void main(String[] args) {
int[] arr = new int[] {1,2,3};
System.out.println(minMoveNumber1(arr));
System.out.println(minMoveNumber2(arr));
System.out.println(minMoveNumber3(arr));
}
public static int minMoveNumber1(int[] nums) {
if (nums == null || nums.length <= 1) {
return 0;
}
Arrays.sort(nums);
int sum = 0;
for (int i=0;i<nums.length;i++) {
sum += Math.abs(nums[nums.length/2] - nums[i]);
}
return sum;
}
public static int minMoveNumber2(int[] nums) {
if (nums == null || nums.length <= 1) {
return 0;
}
int sum = 0;
int mid = selectMid(nums , 0 , nums.length-1 , nums.length/2);
for (int n : nums) {
sum += Math.abs(mid - n);
}
return sum;
}
public static int selectMid(int[] arr , int left , int right , int k) {
if (left == right) {
return arr[left];
}
int p = partition(arr , left , right);
if (k == p) {
return arr[k];
} else if (k < p) {
return selectMid(arr , left , p - 1 , k);
} else {
return selectMid(arr , p + 1 , right , k);
}
}
public static int partition(int[] arr , int left , int right) {
int p = arr[right];
int i = left;
for (int j=left;j<=right;j++) {
if (p > arr[j]) {
swap(arr , i , j);
i++;
}
}
swap(arr , right , i);
return i;
}
public static void swap(int[] arr , int left , int right) {
int temp = arr[left];
arr[left] = arr[right];
arr[right] = temp;
}
public static int minMoveNumber3(int[] nums) {
if (nums == null || nums.length <= 1) {
return 0;
}
int result = 0;
Arrays.sort(nums);
int left = 0;
int right = nums.length - 1;
while (left < right) {
result += nums[right] - nums[left];
left++;
right--;
}
return result;
}
}