![7eb7a20c250428a381937885a7f014d1.png](https://i-blog.csdnimg.cn/blog_migrate/bf67175b5b47bce0c724aae529054389.jpeg)
462. Minimum Moves to Equal Array Elements II
description:
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]
solution:
what?
定义移动操作为(选择数组中一个特定元素,对它执行自增或自减操作),经过多次移动,使得数组所有元素相同。
how?
LeetCode-453等价于将一个特定元素自减,所以要想使得数组所有元素相同,至少最后所有元素相同的那个值为最开始数组中的最小值。
而这道题允许我们对特定元素执行加法或减法操作,意思是最后所有元素相同的那个值可以不再是最开始数组中的最小值,而是中间的某个值,那么试一试平均数、中位数行不行!
注意平均数不为整数、中位数位于两个数中间的情况,要分两种情况考虑,取最小值。
平均数被gank了,其实随便举个例子就能知道。
[1,1,1,1,1,1,9]
傻瓜都知道肯定选中位数而不是平均数,使得总步长最短。
//7ms
//seem not be the average number, but medium number.
class Solution {
//length of nums: [0, 10000].
public int minMoves2(int[] nums) {
if(nums.length==0 || nums.length==1) return 0;
int ans=0;
//sort the nums
Arrays.sort(nums);
//select medium of nums
int middle=nums.length/2;
if(nums.length % 2 == 1) {
int m=nums[middle];
for(int num: nums) {
ans += Math.abs(num-m);
}
return ans;
}else {
int m1=nums[middle], ans1=0;
int m2=nums[middle-1], ans2=0;
for(int num: nums) ans1 += Math.abs(num-m1);
for(int num: nums) ans2 += Math.abs(num-m2);
return Math.min(ans1, ans2);
}
}
}
// T:O(nlogn)
// S:O(1)
complexity:
- TT
- O(nlogn)O(nlogn):只要对数组排序,寻找中位数所花费的时间。
- SS
- O(1)O(1)
tags:
- Math